1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
4 ** Authors: Martin Trapp, Christian Schaefer
16 # include "irgraph_t.h"
23 ir_graph *current_ir_graph;
25 #if USE_EXPICIT_PHI_IN_STACK
26 /* really defined in ircons.c */
27 typedef struct Phi_in_stack Phi_in_stack;
28 Phi_in_stack *new_Phi_in_stack();
29 void free_Phi_in_stack(Phi_in_stack *s);
32 /* Allocates a list of nodes:
33 - The start block containing a start node and Proj nodes for it's four
34 results (X, M, P, Tuple).
35 - The end block containing an end node. This block is not matured after
36 new_ir_graph as predecessors need to be added to it.
37 - The current block, which is empty and also not matured.
38 Further it allocates several datastructures needed for graph construction
42 new_ir_graph (entity *ent, int n_loc)
48 res = (ir_graph *) malloc (sizeof (ir_graph));
49 current_ir_graph = res;
50 add_irp_irg(res); /* remember this graph global. */
52 /** Internal information for graph construction either held in the graph or
53 *** initialized for each graph. **/
54 #if PRECISE_EXC_CONTEXT
55 res->n_loc = n_loc + 1 + 1; /* number of local variables that are never
56 dereferenced in this graph plus one for
57 the store plus one for links to fragile
58 operations. n_loc is not the number of
59 parameters to the procedure! */
61 res->n_loc = n_loc + 1; /* number of local variables that are never
62 dereferenced in this graph plus one for
63 the store. This is not the number of parameters
67 res->visited = 0; /* visited flag, for the ir walker */
68 res->block_visited=0; /* visited flag, for the 'block'-walker */
70 #if USE_EXPICIT_PHI_IN_STACK
71 res->Phi_in_stack = new_Phi_in_stack(); /* A stack needed for automatic Phi
74 res->obst = (struct obstack *) xmalloc (sizeof (struct obstack));
75 obstack_init (res->obst);
76 res->value_table = new_identities (); /* value table for global value
77 numbering for optimizing use in
80 /** Type inforamtion for the procedure of the graph **/
82 set_entity_irg(ent, res);
84 /** A type that represents the stack frame. A class type so that it can
85 contain "inner" methods as in Pascal. **/
86 res->frame_type = new_type_class(mangle(get_entity_ident(ent), id_from_str("frame_tp", 8)));
88 /** Nodes needed in every graph **/
89 res->end_block = new_immBlock ();
90 res->end = new_End ();
92 res->start_block = new_immBlock ();
93 res->start = new_Start ();
94 res->bad = new_ir_node (res, res->start_block, op_Bad, mode_T, 0, NULL);
96 /* Proj results of start node */
97 projX = new_Proj (res->start, mode_X, pns_initial_exec);
98 set_store (new_Proj (res->start, mode_M, pns_global_store));
99 res->frame = new_Proj (res->start, mode_p, pns_frame_base);
100 res->globals = new_Proj (res->start, mode_p, pns_globals);
101 res->args = new_Proj (res->start, mode_T, pns_args);
103 add_in_edge(res->start_block, projX);
105 * The code generation needs it. leave it in now.
106 * Use of this edge is matter of discussion, unresolved. Also possible:
107 * add_in_edge(res->start_block, res->start_block), but invalid typed.
109 mature_block (res->current_block);
111 /** Make a block to start with **/
112 first_block = new_immBlock ();
113 add_in_edge (first_block, projX);
119 /* Make a rudimentary ir graph for the constant code.
120 Must look like a correct irg, spare everything else. */
121 ir_graph *new_const_code_irg() {
125 res = (ir_graph *) malloc (sizeof (ir_graph));
126 current_ir_graph = res;
127 res->n_loc = 1; /* Only the memory. */
128 res->visited = 0; /* visited flag, for the ir walker */
129 res->block_visited=0; /* visited flag, for the 'block'-walker */
130 #if USE_EXPICIT_PHI_IN_STACK
131 res->Phi_in_stack = NULL;
133 res->obst = (struct obstack *) xmalloc (sizeof (struct obstack));
134 obstack_init (res->obst);
135 res->value_table = new_identities (); /* value table for global value
136 numbering for optimizing use in
139 res->frame_type = NULL;
140 res->start_block = new_immBlock ();
141 res->end_block = new_immBlock ();
142 res->end = new_End ();
143 mature_block(get_cur_block());
144 res->bad = new_ir_node (res, res->start_block, op_Bad, mode_T, 0, NULL);
145 res->start = new_Start ();
146 /* Proj results of start node */
147 projX = new_Proj (res->start, mode_X, pns_initial_exec);
148 set_store (new_Proj (res->start, mode_M, pns_global_store));
149 add_in_edge(res->start_block, projX);
150 mature_block (res->current_block);
151 add_in_edge (new_immBlock (), projX);
152 mature_block(get_cur_block());
153 /* Set the visited flag high enough that the block will never be visited. */
154 set_irn_visited(get_cur_block(), -1);
155 set_Block_block_visited(get_cur_block(), -1);
156 set_Block_block_visited(res->start_block, -1);
162 /* Frees the passed irgraph.
163 Deallocates all nodes in this graph and the ir_graph structure.
164 Sets the field irgraph in the corresponding entity to NULL.
165 Does not remove the irgraph from the list in irprog (requires
166 inefficient search, call remove_irp_irg by hand).
167 Does not free types, entities or modes that are used only by this
168 graph, nor the entity standing for this graph. */
169 void free_ir_graph (ir_graph *irg) {
170 set_entity_irg(irg->ent, NULL);
172 #if USE_EXPICIT_PHI_IN_STACK
173 free_Phi_in_stack(irg->Phi_in_stack);
178 /* access routines for all ir_graph attributes:
180 {attr type} get_irg_{attribute name} (ir_graph *irg);
181 void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
184 get_irg_start_block (ir_graph *irg)
186 return irg->start_block;
190 set_irg_start_block (ir_graph *irg, ir_node *node)
192 irg->start_block = node;
196 get_irg_start (ir_graph *irg)
202 set_irg_start(ir_graph *irg, ir_node *node)
208 get_irg_end_block (ir_graph *irg)
210 return irg->end_block;
214 set_irg_end_block (ir_graph *irg, ir_node *node)
216 irg->end_block = node;
220 get_irg_end (ir_graph *irg)
226 set_irg_end (ir_graph *irg, ir_node *node)
232 get_irg_cstore (ir_graph *irg)
238 set_irg_cstore (ir_graph *irg, ir_node *node)
244 get_irg_frame (ir_graph *irg)
250 set_irg_frame (ir_graph *irg, ir_node *node)
256 get_irg_globals (ir_graph *irg)
262 set_irg_globals (ir_graph *irg, ir_node *node)
268 get_irg_args (ir_graph *irg)
274 set_irg_args (ir_graph *irg, ir_node *node)
280 get_irg_bad (ir_graph *irg)
286 set_irg_bad (ir_graph *irg, ir_node *node)
292 get_irg_current_block (ir_graph *irg)
294 return irg->current_block;
298 set_irg_current_block (ir_graph *irg, ir_node *node)
300 irg->current_block = node;
304 get_irg_ent (ir_graph *irg)
306 assert(irg && irg->ent);
311 set_irg_ent (ir_graph *irg, entity *ent)
317 get_irg_frame_type (ir_graph *irg)
319 assert(irg && irg->frame_type);
320 return irg->frame_type;
324 set_irg_frame_type (ir_graph *irg, type *ftp)
326 irg->frame_type = ftp;
330 get_irg_n_loc (ir_graph *irg)
336 set_irg_n_loc (ir_graph *irg, int n_loc)
342 get_irg_visited (ir_graph *irg)
348 set_irg_visited (ir_graph *irg, unsigned long visited)
350 irg->visited = visited;
354 inc_irg_visited (ir_graph *irg)
356 irg->visited = irg->visited++;
360 get_irg_block_visited (ir_graph *irg)
362 return irg->block_visited;
366 set_irg_block_visited (ir_graph *irg, unsigned long visited)
368 irg->block_visited = visited;
372 inc_irg_block_visited (ir_graph *irg)
374 irg->block_visited = irg->block_visited++;