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"
53 #define INITIAL_IDX_IRN_MAP_SIZE 1024
56 * Indicates, whether additional data can be registered to graphs.
57 * If set to 1, this is not possible anymore.
59 static int forbid_new_data = 0;
62 * The amount of additional space for custom data to be allocated upon
63 * creating a new graph.
65 static size_t additional_graph_data_size = 0;
67 ir_graph *current_ir_graph;
68 ir_graph *get_current_ir_graph(void)
70 return current_ir_graph;
73 void set_current_ir_graph(ir_graph *graph)
75 current_ir_graph = graph;
78 #ifdef INTERPROCEDURAL_VIEW
79 int firm_interprocedural_view = 0;
81 int (get_interprocedural_view)(void)
83 return _get_interprocedural_view();
86 void (set_interprocedural_view)(int state)
88 firm_interprocedural_view = state;
90 /* set function vectors for faster access */
92 _get_irn_arity = _get_irn_inter_arity;
93 _get_irn_n = _get_irn_inter_n;
96 _get_irn_arity = _get_irn_intra_arity;
97 _get_irn_n = _get_irn_intra_n;
102 /** contains the suffix for frame type names */
103 static ident *frame_type_suffix = NULL;
105 /* initialize the IR graph module */
106 void firm_init_irgraph(void)
108 frame_type_suffix = new_id_from_str(FRAME_TP_SUFFIX);
113 * Allocate a new IR graph.
114 * This function respects the registered graph data. The only reason for
115 * this function is, that there are two locations, where graphs are
116 * allocated (new_r_ir_graph, new_const_code_irg).
117 * @return Memory for a new graph.
119 static ir_graph *alloc_graph(void)
122 size_t size = sizeof(ir_graph) + additional_graph_data_size;
123 char *ptr = XMALLOCNZ(char, size);
125 res = (ir_graph *)(ptr + additional_graph_data_size);
126 res->kind = k_ir_graph;
128 /* initialize the idx->node map. */
129 res->idx_irn_map = NEW_ARR_F(ir_node *, INITIAL_IDX_IRN_MAP_SIZE);
130 memset(res->idx_irn_map, 0, INITIAL_IDX_IRN_MAP_SIZE * sizeof(res->idx_irn_map[0]));
136 * Frees an allocated IR graph
138 static void free_graph(ir_graph *irg)
140 char *ptr = (char *)irg;
143 for (i = 0; i < EDGE_KIND_LAST; ++i)
144 edges_deactivate_kind(irg, i);
145 DEL_ARR_F(irg->idx_irn_map);
146 free(ptr - additional_graph_data_size);
150 * Set the number of locals for a given graph.
152 * @param irg the graph
153 * @param n_loc number of locals
155 void irg_set_nloc(ir_graph *res, int n_loc)
157 assert(res->phase_state == phase_building);
159 if (get_opt_precise_exc_context()) {
160 res->n_loc = n_loc + 1 + 1; /* number of local variables that are never
161 dereferenced in this graph plus one for
162 the store plus one for links to fragile
163 operations. n_loc is not the number of
164 parameters to the procedure! */
166 res->n_loc = n_loc + 1; /* number of local variables that are never
167 dereferenced in this graph plus one for
168 the store. This is not the number of parameters
171 if (res->loc_descriptions) {
172 xfree(res->loc_descriptions);
173 res->loc_descriptions = NULL;
177 /* Allocates a list of nodes:
178 - The start block containing a start node and Proj nodes for it's four
179 results (X, M, P, Tuple).
180 - The end block containing an end node. This block is not matured after
181 new_ir_graph as predecessors need to be added to it.
182 - The current block, which is empty and also not matured.
183 Further it allocates several datastructures needed for graph construction
186 ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc)
189 ir_node *first_block;
190 ir_node *end, *start, *start_block, *initial_mem, *projX, *bad;
194 /* inform statistics here, as blocks will be already build on this graph */
195 hook_new_graph(res, ent);
197 current_ir_graph = res;
199 /*-- initialized for each graph. --*/
200 res->kind = k_ir_graph;
201 res->obst = XMALLOC(struct obstack);
202 obstack_init(res->obst);
204 res->phase_state = phase_building;
205 irg_set_nloc(res, n_loc);
207 /* descriptions will be allocated on demand */
208 res->loc_descriptions = NULL;
210 res->visited = 0; /* visited flag, for the ir walker */
211 res->block_visited = 0; /* visited flag, for the 'block'-walker */
213 res->extbb_obst = NULL;
215 res->last_node_idx = 0;
217 res->value_table = new_identities(); /* value table for global value
218 numbering for optimizing use in iropt.c */
221 res->inline_property = irg_inline_any;
222 res->additional_properties = mtp_property_inherited; /* inherited from type */
224 res->irg_pinned_state = op_pin_state_pinned;
225 res->outs_state = outs_none;
226 res->dom_state = dom_none;
227 res->pdom_state = dom_none;
228 res->typeinfo_state = ir_typeinfo_none;
229 set_irp_typeinfo_inconsistent(); /* there is a new graph with typeinfo_none. */
230 res->callee_info_state = irg_callee_info_none;
231 res->loopinfo_state = loopinfo_none;
232 res->class_cast_state = ir_class_casts_transitive;
233 res->extblk_state = ir_extblk_info_none;
234 res->execfreq_state = exec_freq_none;
235 res->fp_model = fp_model_precise;
236 res->entity_usage_state = ir_entity_usage_not_computed;
237 res->mem_disambig_opt = aa_opt_inherited;
239 /*-- Type information for the procedure of the graph --*/
241 set_entity_irg(ent, res);
243 /*-- a class type so that it can contain "inner" methods as in Pascal. --*/
244 res->frame_type = new_type_frame();
246 /* the Anchor node must be created first */
247 res->anchor = new_Anchor(res);
249 /*-- Nodes needed in every graph --*/
250 set_irg_end_block (res, new_immBlock());
251 set_cur_block(get_irg_end_block(res));
253 set_irg_end (res, end);
254 set_irg_end_reg (res, end);
255 set_irg_end_except(res, end);
257 start_block = new_immBlock();
258 set_cur_block(start_block);
259 set_irg_start_block(res, start_block);
260 bad = new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL);
261 bad->attr.irg.irg = res;
262 set_irg_bad (res, bad);
263 set_irg_no_mem (res, new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL));
265 set_irg_start (res, start);
267 /* Proj results of start node */
268 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
269 set_irg_initial_exec (res, projX);
270 set_irg_frame (res, new_Proj(start, mode_P_data, pn_Start_P_frame_base));
271 set_irg_tls (res, new_Proj(start, mode_P_data, pn_Start_P_tls));
272 set_irg_args (res, new_Proj(start, mode_T, pn_Start_T_args));
273 initial_mem = new_Proj(start, mode_M, pn_Start_M);
274 set_irg_initial_mem(res, initial_mem);
276 set_store(initial_mem);
278 res->index = get_irp_new_irg_idx();
280 res->graph_nr = get_irp_new_node_nr();
283 mature_immBlock(res->current_block);
285 /*-- Make a block to start with --*/
286 first_block = new_immBlock();
287 set_cur_block(first_block);
288 add_immBlock_pred(first_block, projX);
290 res->method_execution_frequency = -1.0;
291 res->estimated_node_count = 0;
296 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_graph *res = alloc_graph();
314 ir_node *start_block;
317 /* inform statistics here, as blocks will be already build on this graph */
318 hook_new_graph(res, NULL);
320 current_ir_graph = res;
321 res->n_loc = 1; /* Only the memory. */
322 res->visited = 0; /* visited flag, for the ir walker */
323 res->block_visited = 0; /* visited flag, for the 'block'-walker */
324 res->obst = XMALLOC(struct obstack);
325 obstack_init(res->obst);
326 res->extbb_obst = NULL;
328 res->last_node_idx = 0;
330 res->phase_state = phase_building;
331 res->irg_pinned_state = op_pin_state_pinned;
332 res->extblk_state = ir_extblk_info_none;
333 res->fp_model = fp_model_precise;
335 /* value table for global value numbering for optimizing use in iropt.c */
336 res->value_table = new_identities();
338 res->frame_type = NULL;
340 /* the Anchor node must be created first */
341 res->anchor = new_Anchor(res);
343 /* -- The end block -- */
344 end_block = new_immBlock();
345 set_irg_end_block(res, end_block);
346 set_cur_block(end_block);
348 set_irg_end (res, end);
349 set_irg_end_reg (res, end);
350 set_irg_end_except(res, end);
351 mature_immBlock(end_block);
353 /* -- The start block -- */
354 start_block = new_immBlock();
355 set_cur_block(start_block);
356 set_irg_start_block(res, start_block);
357 bad = new_ir_node(NULL, res, start_block, op_Bad, mode_T, 0, NULL);
358 bad->attr.irg.irg = res;
359 set_irg_bad(res, bad);
360 no_mem = new_ir_node(NULL, res, start_block, op_NoMem, mode_M, 0, NULL);
361 set_irg_no_mem(res, no_mem);
363 set_irg_start(res, start);
365 /* Proj results of start node */
366 set_irg_initial_mem(res, new_Proj(start, mode_M, pn_Start_M));
367 projX = new_Proj(start, mode_X, pn_Start_X_initial_exec);
368 mature_immBlock(start_block);
370 body_block = new_immBlock();
371 add_immBlock_pred(body_block, projX);
372 mature_immBlock(body_block); /* mature the 'body' block for expressions */
373 set_cur_block(body_block);
375 /* Set the visited flag high enough that the blocks will never be visited. */
376 set_irn_visited(body_block, -1);
377 set_Block_block_visited(body_block, -1);
378 set_Block_block_visited(start_block, -1);
379 set_irn_visited(start_block, -1);
380 set_irn_visited(bad, -1);
381 set_irn_visited(no_mem, -1);
383 res->phase_state = phase_high;
389 * Pre-Walker: Copies blocks and nodes from the original method graph
390 * to the copied graph.
392 * @param n A node from the original method graph.
393 * @param env The copied graph.
395 static void copy_all_nodes(ir_node *node, void *env)
398 ir_node *new_node = irn_copy_into_irg(node, irg);
400 set_irn_link(node, new_node);
402 /* fix access to entities on the stack frame */
403 if (is_Sel(new_node)) {
404 ir_entity *ent = get_Sel_entity(new_node);
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(new_node, 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 rewire(ir_node *irn, void *env)
426 irn_rewire_inputs(irn);
429 static ir_node *get_new_node(const ir_node *old_node)
431 return (ir_node*) get_irn_link(old_node);
435 * Create a new graph that is a copy of a given one.
437 ir_graph *create_irg_copy(ir_graph *irg)
444 res->visited = 0; /* visited flag, for the ir walker */
445 res->block_visited = 0; /* visited flag, for the 'block'-walker */
446 res->obst = XMALLOC(struct obstack);
447 obstack_init(res->obst);
448 res->extbb_obst = NULL;
450 res->last_node_idx = 0;
452 res->phase_state = irg->phase_state;
453 res->irg_pinned_state = irg->irg_pinned_state;
454 res->extblk_state = ir_extblk_info_none;
455 res->fp_model = irg->fp_model;
457 res->value_table = new_identities();
459 /* clone the frame type here for safety */
460 irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK);
461 res->frame_type = clone_frame_type(irg->frame_type);
463 res->phase_state = irg->phase_state;
465 ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK);
467 /* copy all nodes from the graph irg to the new graph res */
468 irg_walk_anchors(irg, copy_all_nodes, rewire, res);
470 /* copy the Anchor node */
471 res->anchor = get_new_node(irg->anchor);
473 /* -- The end block -- */
474 set_irg_end_block (res, get_new_node(get_irg_end_block(irg)));
475 set_irg_end (res, get_new_node(get_irg_end(irg)));
476 set_irg_end_reg (res, get_new_node(get_irg_end_reg(irg)));
477 set_irg_end_except(res, get_new_node(get_irg_end_except(irg)));
479 /* -- The start block -- */
480 set_irg_start_block(res, get_new_node(get_irg_start_block(irg)));
481 set_irg_bad (res, get_new_node(get_irg_bad(irg)));
482 set_irg_no_mem (res, get_new_node(get_irg_no_mem(irg)));
483 set_irg_start (res, get_new_node(get_irg_start(irg)));
485 /* Proj results of start node */
486 set_irg_initial_mem(res, get_new_node(get_irg_initial_mem(irg)));
488 /* Copy the node count estimation. Would be strange if this
489 is different from the original one. */
490 res->estimated_node_count = irg->estimated_node_count;
492 ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
493 irp_free_resources(irp, IR_RESOURCE_ENTITY_LINK);
498 /* Frees the passed irgraph.
499 Deallocates all nodes in this graph and the ir_graph structure.
500 Sets the field irgraph in the corresponding entity to NULL.
501 Does not remove the irgraph from the list in irprog (requires
502 inefficient search, call remove_irp_irg by hand).
503 Does not free types, entities or modes that are used only by this
504 graph, nor the entity standing for this graph. */
505 void free_ir_graph(ir_graph *irg)
507 assert(is_ir_graph(irg));
509 edges_deactivate(irg);
511 hook_free_graph(irg);
512 if (irg->outs_state != outs_none)
515 free_type(irg->frame_type);
516 if (irg->value_table)
517 del_identities(irg->value_table);
519 set_entity_irg(irg->ent, NULL); /* not set in const code irg */
522 free_End(get_irg_end(irg));
523 obstack_free(irg->obst,NULL);
525 if (irg->loc_descriptions)
526 free(irg->loc_descriptions);
531 /* access routines for all ir_graph attributes:
533 {attr type} get_irg_{attribute name} (ir_graph *irg);
534 void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
536 int (is_ir_graph)(const void *thing)
538 return _is_ir_graph(thing);
542 /* Outputs a unique number for this node */
543 long get_irg_graph_nr(const ir_graph *irg)
545 return irg->graph_nr;
548 long get_irg_graph_nr(const ir_graph *irg)
550 return PTR_TO_INT(irg);
554 int get_irg_idx(const ir_graph *irg)
559 ir_node *(get_idx_irn)(ir_graph *irg, unsigned idx)
561 return _get_idx_irn(irg, idx);
564 ir_node *(get_irg_start_block)(const ir_graph *irg)
566 return _get_irg_start_block(irg);
569 void (set_irg_start_block)(ir_graph *irg, ir_node *node)
571 _set_irg_start_block(irg, node);
574 ir_node *(get_irg_start)(const ir_graph *irg)
576 return _get_irg_start(irg);
579 void (set_irg_start)(ir_graph *irg, ir_node *node)
581 _set_irg_start(irg, node);
584 ir_node *(get_irg_end_block)(const ir_graph *irg)
586 return _get_irg_end_block(irg);
589 void (set_irg_end_block)(ir_graph *irg, ir_node *node)
591 _set_irg_end_block(irg, node);
594 ir_node *(get_irg_end)(const ir_graph *irg)
596 return _get_irg_end(irg);
599 void (set_irg_end)(ir_graph *irg, ir_node *node)
601 _set_irg_end(irg, node);
604 ir_node *(get_irg_end_reg)(const ir_graph *irg)
606 return _get_irg_end_reg(irg);
609 void (set_irg_end_reg)(ir_graph *irg, ir_node *node)
611 _set_irg_end_reg(irg, node);
614 ir_node *(get_irg_end_except)(const ir_graph *irg)
616 return _get_irg_end_except(irg);
619 void (set_irg_end_except)(ir_graph *irg, ir_node *node)
621 assert(get_irn_op(node) == op_EndExcept || is_End(node));
622 _set_irg_end_except(irg, node);
625 ir_node *(get_irg_initial_exec)(const ir_graph *irg)
627 return _get_irg_initial_exec(irg);
630 void (set_irg_initial_exec)(ir_graph *irg, ir_node *node)
632 _set_irg_initial_exec(irg, node);
635 ir_node *(get_irg_frame)(const ir_graph *irg)
637 return _get_irg_frame(irg);
640 void (set_irg_frame)(ir_graph *irg, ir_node *node)
642 _set_irg_frame(irg, node);
645 ir_node *(get_irg_tls)(const ir_graph *irg)
647 return _get_irg_tls(irg);
650 void (set_irg_tls)(ir_graph *irg, ir_node *node)
652 _set_irg_tls(irg, node);
655 ir_node *(get_irg_initial_mem)(const ir_graph *irg)
657 return _get_irg_initial_mem(irg);
660 void (set_irg_initial_mem)(ir_graph *irg, ir_node *node)
662 _set_irg_initial_mem(irg, node);
665 ir_node *(get_irg_args)(const ir_graph *irg)
667 return _get_irg_args(irg);
670 void (set_irg_args)(ir_graph *irg, ir_node *node)
672 _set_irg_args(irg, node);
675 ir_node *(get_irg_bad)(const ir_graph *irg)
677 return _get_irg_bad(irg);
680 void (set_irg_bad)(ir_graph *irg, ir_node *node)
682 _set_irg_bad(irg, node);
685 ir_node *(get_irg_no_mem)(const ir_graph *irg)
687 return _get_irg_no_mem(irg);
690 void (set_irg_no_mem)(ir_graph *irg, ir_node *node)
692 _set_irg_no_mem(irg, node);
695 ir_node *(get_irg_current_block)(const ir_graph *irg)
697 return _get_irg_current_block(irg);
700 void (set_irg_current_block)(ir_graph *irg, ir_node *node)
702 _set_irg_current_block(irg, node);
705 ir_entity *(get_irg_entity)(const ir_graph *irg)
707 return _get_irg_entity(irg);
710 void (set_irg_entity)(ir_graph *irg, ir_entity *ent)
712 _set_irg_entity(irg, ent);
715 ir_type *(get_irg_frame_type)(ir_graph *irg)
717 return _get_irg_frame_type(irg);
720 void (set_irg_frame_type)(ir_graph *irg, ir_type *ftp)
722 _set_irg_frame_type(irg, ftp);
725 /* Returns the value parameter type of an IR graph. */
726 ir_type *get_irg_value_param_type(ir_graph *irg)
728 ir_entity *ent = get_irg_entity(irg);
729 ir_type *mtp = get_entity_type(ent);
730 return get_method_value_param_type(mtp);
733 int get_irg_n_locs(ir_graph *irg)
735 if (get_opt_precise_exc_context())
736 return irg->n_loc - 1 - 1;
738 return irg->n_loc - 1;
741 /* Returns the obstack associated with the graph. */
743 (get_irg_obstack)(const ir_graph *irg) {
744 return _get_irg_obstack(irg);
748 * Returns true if the node n is allocated on the storage of graph irg.
750 * Implementation is GLIBC specific as is uses the internal _obstack_chunk implementation.
752 int node_is_in_irgs_storage(ir_graph *irg, ir_node *n)
754 struct _obstack_chunk *p;
757 * checks weather the ir_node pointer is on the obstack.
758 * A more sophisticated check would test the "whole" ir_node
760 for (p = irg->obst->chunk; p; p = p->prev) {
761 if (((char *)p->contents <= (char *)n) && ((char *)n < (char *)p->limit))
768 irg_phase_state (get_irg_phase_state)(const ir_graph *irg)
770 return _get_irg_phase_state(irg);
773 void (set_irg_phase_state)(ir_graph *irg, irg_phase_state state)
775 _set_irg_phase_state(irg, state);
778 op_pin_state (get_irg_pinned)(const ir_graph *irg)
780 return _get_irg_pinned(irg);
783 irg_outs_state (get_irg_outs_state)(const ir_graph *irg)
785 return _get_irg_outs_state(irg);
788 void (set_irg_outs_inconsistent)(ir_graph *irg)
790 _set_irg_outs_inconsistent(irg);
793 irg_extblk_state (get_irg_extblk_state)(const ir_graph *irg)
795 return _get_irg_extblk_state(irg);
798 void (set_irg_extblk_inconsistent)(ir_graph *irg)
800 _set_irg_extblk_inconsistent(irg);
803 irg_dom_state (get_irg_dom_state)(const ir_graph *irg)
805 return _get_irg_dom_state(irg);
808 irg_dom_state (get_irg_postdom_state)(const ir_graph *irg)
810 return _get_irg_postdom_state(irg);
813 void (set_irg_doms_inconsistent)(ir_graph *irg)
815 _set_irg_doms_inconsistent(irg);
818 irg_loopinfo_state (get_irg_loopinfo_state)(const ir_graph *irg)
820 return _get_irg_loopinfo_state(irg);
823 void (set_irg_loopinfo_state)(ir_graph *irg, irg_loopinfo_state s)
825 _set_irg_loopinfo_state(irg, s);
828 void (set_irg_loopinfo_inconsistent)(ir_graph *irg)
830 _set_irg_loopinfo_inconsistent(irg);
833 void set_irp_loopinfo_inconsistent(void)
836 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
837 set_irg_loopinfo_inconsistent(get_irp_irg(i));
843 void (set_irg_pinned)(ir_graph *irg, op_pin_state p)
845 _set_irg_pinned(irg, p);
848 irg_callee_info_state (get_irg_callee_info_state)(const ir_graph *irg)
850 return _get_irg_callee_info_state(irg);
853 void (set_irg_callee_info_state)(ir_graph *irg, irg_callee_info_state s)
855 _set_irg_callee_info_state(irg, s);
858 irg_inline_property (get_irg_inline_property)(const ir_graph *irg)
860 return _get_irg_inline_property(irg);
863 void (set_irg_inline_property)(ir_graph *irg, irg_inline_property s)
865 _set_irg_inline_property(irg, s);
868 unsigned (get_irg_additional_properties)(const ir_graph *irg)
870 return _get_irg_additional_properties(irg);
873 void (set_irg_additional_properties)(ir_graph *irg, unsigned property_mask)
875 _set_irg_additional_properties(irg, property_mask);
878 void (set_irg_additional_property)(ir_graph *irg, mtp_additional_property flag)
880 _set_irg_additional_property(irg, flag);
883 void (set_irg_link)(ir_graph *irg, void *thing)
885 _set_irg_link(irg, thing);
888 void *(get_irg_link)(const ir_graph *irg)
890 return _get_irg_link(irg);
893 ir_visited_t (get_irg_visited)(const ir_graph *irg)
895 return _get_irg_visited(irg);
898 /** maximum visited flag content of all ir_graph visited fields. */
899 static ir_visited_t max_irg_visited = 0;
901 void set_irg_visited(ir_graph *irg, ir_visited_t visited)
903 irg->visited = visited;
904 if (irg->visited > max_irg_visited) {
905 max_irg_visited = irg->visited;
909 void inc_irg_visited(ir_graph *irg)
912 if (irg->visited > max_irg_visited) {
913 max_irg_visited = irg->visited;
917 ir_visited_t get_max_irg_visited(void)
919 return max_irg_visited;
922 void set_max_irg_visited(int val)
924 max_irg_visited = val;
927 ir_visited_t inc_max_irg_visited(void)
931 for (i = 0; i < get_irp_n_irgs(); i++)
932 assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
934 return ++max_irg_visited;
937 ir_visited_t (get_irg_block_visited)(const ir_graph *irg)
939 return _get_irg_block_visited(irg);
942 void (set_irg_block_visited)(ir_graph *irg, ir_visited_t visited)
944 _set_irg_block_visited(irg, visited);
947 void (inc_irg_block_visited)(ir_graph *irg)
949 _inc_irg_block_visited(irg);
952 /* Return the floating point model of this graph. */
953 unsigned (get_irg_fp_model)(const ir_graph *irg)
955 return _get_irg_fp_model(irg);
958 /* Sets the floating point model for this graph. */
959 void set_irg_fp_model(ir_graph *irg, unsigned model)
961 irg->fp_model = model;
965 * walker Start->End: places Proj nodes into the same block
966 * as it's predecessors
971 static void normalize_proj_walker(ir_node *n, void *env)
975 ir_node *pred = get_Proj_pred(n);
976 ir_node *block = get_nodes_block(pred);
978 set_nodes_block(n, block);
982 /* move Proj nodes into the same block as its predecessors */
983 void normalize_proj_nodes(ir_graph *irg)
985 irg_walk_graph(irg, NULL, normalize_proj_walker, NULL);
986 set_irg_outs_inconsistent(irg);
989 /* set a description for local value n */
990 void set_irg_loc_description(ir_graph *irg, int n, void *description)
992 assert(0 <= n && n < irg->n_loc);
994 if (! irg->loc_descriptions)
995 irg->loc_descriptions = XMALLOCNZ(void*, irg->n_loc);
997 irg->loc_descriptions[n] = description;
1000 /* get the description for local value n */
1001 void *get_irg_loc_description(ir_graph *irg, int n)
1003 assert(0 <= n && n < irg->n_loc);
1004 return irg->loc_descriptions ? irg->loc_descriptions[n] : NULL;
1007 void irg_register_phase(ir_graph *irg, ir_phase_id id, ir_phase *phase)
1009 assert(id <= PHASE_LAST);
1010 assert(irg->phases[id] == NULL);
1011 irg->phases[id] = phase;
1014 void irg_invalidate_phases(ir_graph *irg)
1017 for (p = 0; p <= PHASE_LAST; ++p) {
1018 ir_phase *phase = irg->phases[p];
1023 irg->phases[p] = NULL;
1028 void ir_reserve_resources(ir_graph *irg, ir_resources_t resources)
1030 assert((resources & ~IR_RESOURCE_LOCAL_MASK) == 0);
1031 assert((irg->reserved_resources & resources) == 0);
1032 irg->reserved_resources |= resources;
1035 void ir_free_resources(ir_graph *irg, ir_resources_t resources)
1037 assert((irg->reserved_resources & resources) == resources);
1038 irg->reserved_resources &= ~resources;
1041 ir_resources_t ir_resources_reserved(const ir_graph *irg)
1043 return irg->reserved_resources;
1047 /* Returns a estimated node count of the irg. */
1048 unsigned (get_irg_estimated_node_cnt)(const ir_graph *irg)
1050 return _get_irg_estimated_node_cnt(irg);
1053 /* Returns the last irn index for this graph. */
1054 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)
1062 assert(!forbid_new_data && "Too late to register additional node data");
1064 if (forbid_new_data)
1067 return additional_graph_data_size += size;
1070 void (set_irg_state)(ir_graph *irg, ir_graph_state_t state)
1072 _set_irg_state(irg, state);
1075 void (clear_irg_state)(ir_graph *irg, ir_graph_state_t state)
1077 _clear_irg_state(irg, state);
1080 int (is_irg_state)(const ir_graph *irg, ir_graph_state_t state)
1082 return _is_irg_state(irg, state);