da6243348fe00463239479951b4fa3fe81997217
[libfirm] / ir / ir / irgraph.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Authors: Martin Trapp, Christian Schaefer
5 **
6 **
7 */
8
9 /* $Id$ */
10
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14
15 # include "ircons.h"
16 # include "irgraph_t.h"
17 # include "irprog.h"
18 # include "iropt_t.h"
19 # include "array.h"
20 # include "irgmod.h"
21 # include "mangle.h"
22
23 ir_graph *current_ir_graph;
24
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);
30 #endif
31
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
39    and optimization.
40 */
41 ir_graph *
42 new_ir_graph (entity *ent, int n_loc)
43 {
44   ir_graph *res;
45   ir_node *first_block;
46   ir_node *projX;
47
48   res = (ir_graph *) malloc (sizeof (ir_graph));
49   current_ir_graph = res;
50   add_irp_irg(res);          /* remember this graph global. */
51
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!  */
60 #else
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
64                               to the procedure!  */
65 #endif
66
67   res->visited = 0;     /* visited flag, for the ir walker */
68   res->block_visited=0; /* visited flag, for the 'block'-walker */
69
70 #if USE_EXPICIT_PHI_IN_STACK
71   res->Phi_in_stack = new_Phi_in_stack();  /* A stack needed for automatic Phi
72                                 generation */
73 #endif
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
78                                            iropt.c */
79
80   /** Type inforamtion for the procedure of the graph **/
81   res->ent = ent;
82   set_entity_irg(ent, res);
83
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)));
87
88   /** Nodes needed in every graph **/
89   res->end_block = new_immBlock ();
90   res->end       = new_End ();
91
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);
95
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);
102
103   add_in_edge(res->start_block, projX);
104   /*
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.
108    */
109   mature_block (res->current_block);
110
111   /** Make a block to start with **/
112   first_block = new_immBlock ();
113   add_in_edge (first_block, projX);
114
115   return res;
116 }
117
118 /* Frees the passed irgraph.
119    Deallocates all nodes in this graph and the ir_graph structure.
120    Sets the field irgraph in the corresponding entity to NULL.
121    Does not remove the irgraph from the list in irprog (requires
122    inefficient search, call remove_irp_irg by hand).
123    Does not free types, entities or modes that are used only by this
124    graph, nor the entity standing for this graph. */
125 void free_ir_graph (ir_graph *irg) {
126   set_entity_irg(irg->ent, NULL);
127   free(irg->obst);
128 #if USE_EXPICIT_PHI_IN_STACK
129   free_Phi_in_stack(irg->Phi_in_stack);
130 #endif
131   free(irg);
132 }
133
134 /* access routines for all ir_graph attributes:
135    templates:
136    {attr type} get_irg_{attribute name} (ir_graph *irg);
137    void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
138
139 ir_node *
140 get_irg_start_block (ir_graph *irg)
141 {
142   return irg->start_block;
143 }
144
145 void
146 set_irg_start_block (ir_graph *irg, ir_node *node)
147 {
148   irg->start_block = node;
149 }
150
151 ir_node *
152 get_irg_start (ir_graph *irg)
153 {
154   return irg->start;
155 }
156
157 void
158 set_irg_start(ir_graph *irg, ir_node *node)
159 {
160   irg->start = node;
161 }
162
163 ir_node *
164 get_irg_end_block (ir_graph *irg)
165 {
166   return irg->end_block;
167 }
168
169 void
170 set_irg_end_block (ir_graph *irg, ir_node *node)
171 {
172   irg->end_block = node;
173 }
174
175 ir_node *
176 get_irg_end (ir_graph *irg)
177 {
178   return irg->end;
179 }
180
181 void
182 set_irg_end (ir_graph *irg, ir_node *node)
183 {
184   irg->end = node;
185 }
186
187 ir_node *
188 get_irg_cstore (ir_graph *irg)
189 {
190   return irg->cstore;
191 }
192
193 void
194 set_irg_cstore (ir_graph *irg, ir_node *node)
195 {
196   irg->cstore = node;
197 }
198
199 ir_node *
200 get_irg_frame (ir_graph *irg)
201 {
202   return irg->frame;
203 }
204
205 void
206 set_irg_frame (ir_graph *irg, ir_node *node)
207 {
208   irg->frame = node;
209 }
210
211 ir_node *
212 get_irg_globals (ir_graph *irg)
213 {
214   return irg->globals;
215 }
216
217 void
218 set_irg_globals (ir_graph *irg, ir_node *node)
219 {
220   irg->globals = node;
221 }
222
223 ir_node *
224 get_irg_args (ir_graph *irg)
225 {
226   return irg->args;
227 }
228
229 void
230 set_irg_args (ir_graph *irg, ir_node *node)
231 {
232   irg->args = node;
233 }
234
235 ir_node *
236 get_irg_bad (ir_graph *irg)
237 {
238   return irg->bad;
239 }
240
241 void
242 set_irg_bad (ir_graph *irg, ir_node *node)
243 {
244   irg->bad = node;
245 }
246
247 ir_node *
248 get_irg_current_block (ir_graph *irg)
249 {
250   return irg->current_block;
251 }
252
253 void
254 set_irg_current_block (ir_graph *irg, ir_node *node)
255 {
256   irg->current_block = node;
257 }
258
259 entity *
260 get_irg_ent (ir_graph *irg)
261 {
262   assert(irg && irg->ent);
263   return irg->ent;
264 }
265
266 void
267 set_irg_ent (ir_graph *irg, entity *ent)
268 {
269   irg->ent = ent;
270 }
271
272 type *
273 get_irg_frame_type (ir_graph *irg)
274 {
275   assert(irg && irg->frame_type);
276   return irg->frame_type;
277 }
278
279 void
280 set_irg_frame_type (ir_graph *irg, type *ftp)
281 {
282   irg->frame_type = ftp;
283 }
284
285 int
286 get_irg_n_loc (ir_graph *irg)
287 {
288   return irg->n_loc;
289 }
290
291 void
292 set_irg_n_loc (ir_graph *irg, int n_loc)
293 {
294   irg->n_loc = n_loc;
295 }
296
297 unsigned long
298 get_irg_visited (ir_graph *irg)
299 {
300   return irg->visited;
301 }
302
303 void
304 set_irg_visited (ir_graph *irg, unsigned long visited)
305 {
306   irg->visited = visited;
307 }
308
309 void
310 inc_irg_visited (ir_graph *irg)
311 {
312   irg->visited = irg->visited++;
313 }
314
315 unsigned long
316 get_irg_block_visited (ir_graph *irg)
317 {
318   return irg->block_visited;
319 }
320
321 void
322 set_irg_block_visited (ir_graph *irg, unsigned long visited)
323 {
324   irg->block_visited = visited;
325 }
326
327 void
328 inc_irg_block_visited (ir_graph *irg)
329 {
330   irg->block_visited = irg->block_visited++;
331 }