added Id tag
[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
22 ir_graph *current_ir_graph;
23
24 #if USE_EXPICIT_PHI_IN_STACK
25 /* really defined in ircons.c */
26 typedef struct Phi_in_stack Phi_in_stack;
27 Phi_in_stack *new_Phi_in_stack();
28 void free_Phi_in_stack(Phi_in_stack *s);
29 #endif
30
31 /* Allocates a list of nodes:
32     - The start block containing a start node and Proj nodes for it's four
33       results (X, M, P, Tuple).
34     - The end block containing an end node. This block is not matured after
35       new_ir_graph as predecessors need to be added to it.
36     - The current block, which is empty and also not matured.
37    Further it allocates several datastructures needed for graph construction
38    and optimization.
39 */
40 ir_graph *
41 new_ir_graph (entity *ent, int n_loc)
42 {
43   ir_graph *res;
44   ir_node *first_block;
45   ir_node *projX;
46
47   res = (ir_graph *) malloc (sizeof (ir_graph));
48   current_ir_graph = res;
49   add_irp_irg(res);          /* remember this graph global. */
50
51   /** Internal information for graph construction either held in the graph or
52   *** initialized for each graph. **/
53 #if PRECISE_EXC_CONTEXT
54   res->n_loc = n_loc + 1 + 1; /* number of local variables that are never
55                                  dereferenced in this graph plus one for
56                                  the store plus one for links to fragile
57                                  operations.  n_loc is not the number of
58                                  parameters to the procedure!  */
59 #else
60   res->n_loc = n_loc + 1;  /* number of local variables that are never
61                               dereferenced in this graph plus one for
62                               the store. This is not the number of parameters
63                               to the procedure!  */
64 #endif
65
66   res->visited = 0;     /* visited flag, for the ir walker */
67   res->block_visited=0; /* visited flag, for the 'block'-walker */
68
69 #if USE_EXPICIT_PHI_IN_STACK
70   res->Phi_in_stack = new_Phi_in_stack();  /* A stack needed for automatic Phi
71                                 generation */
72 #endif
73   res->obst      = (struct obstack *) xmalloc (sizeof (struct obstack));
74   obstack_init (res->obst);
75   res->value_table = new_identities (); /* value table for global value
76                                            numbering for optimizing use in
77                                            iropt.c */
78
79   /** Type inforamtion for the procedure of the graph **/
80   res->ent = ent;
81   set_entity_irg(ent, res);
82
83   /** Nodes needed in every graph **/
84   res->end_block = new_immBlock ();
85   res->end       = new_End ();
86
87   res->start_block = new_immBlock ();
88   res->start   = new_Start ();
89   res->bad     = new_ir_node (res, res->start_block, op_Bad, mode_T, 0, NULL);
90
91   /* Proj results of start node */
92   projX        = new_Proj (res->start, mode_X, pns_initial_exec);
93   set_store (new_Proj (res->start, mode_M, pns_global_store));
94   res->frame   = new_Proj (res->start, mode_p, pns_frame_base);
95   res->globals = new_Proj (res->start, mode_p, pns_globals);
96   res->args    = new_Proj (res->start, mode_T, pns_args);
97
98   add_in_edge(res->start_block, projX);
99   /*
100    * The code generation needs it. leave it in now.
101    * Use of this edge is matter of discussion, unresolved. Also possible:
102    * add_in_edge(res->start_block, res->start_block), but invalid typed.
103    */
104   mature_block (res->current_block);
105
106   /** Make a block to start with **/
107   first_block = new_immBlock ();
108   add_in_edge (first_block, projX);
109
110   return res;
111 }
112
113 /* Frees the passed irgraph.
114    Deallocates all nodes in this graph and the ir_graph structure.
115    Sets the field irgraph in the corresponding entity to NULL.
116    Does not remove the irgraph from the list in irprog (requires
117    inefficient search, call remove_irp_irg by hand).
118    Does not free types, entities or modes that are used only by this
119    graph, nor the entity standing for this graph. */
120 void free_ir_graph (ir_graph *irg) {
121   set_entity_irg(irg->ent, NULL);
122   free(irg->obst);
123 #if USE_EXPICIT_PHI_IN_STACK
124   free_Phi_in_stack(irg->Phi_in_stack);
125 #endif
126   free(irg);
127 }
128
129 /* access routines for all ir_graph attributes:
130    templates:
131    {attr type} get_irg_{attribute name} (ir_graph *irg);
132    void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
133
134 ir_node *
135 get_irg_start_block (ir_graph *irg)
136 {
137   return irg->start_block;
138 }
139
140 void
141 set_irg_start_block (ir_graph *irg, ir_node *node)
142 {
143   irg->start_block = node;
144 }
145
146 ir_node *
147 get_irg_start (ir_graph *irg)
148 {
149   return irg->start;
150 }
151
152 void
153 set_irg_start(ir_graph *irg, ir_node *node)
154 {
155   irg->start = node;
156 }
157
158 ir_node *
159 get_irg_end_block (ir_graph *irg)
160 {
161   return irg->end_block;
162 }
163
164 void
165 set_irg_end_block (ir_graph *irg, ir_node *node)
166 {
167   irg->end_block = node;
168 }
169
170 ir_node *
171 get_irg_end (ir_graph *irg)
172 {
173   return irg->end;
174 }
175
176 void
177 set_irg_end (ir_graph *irg, ir_node *node)
178 {
179   irg->end = node;
180 }
181
182 ir_node *
183 get_irg_cstore (ir_graph *irg)
184 {
185   return irg->cstore;
186 }
187
188 void
189 set_irg_cstore (ir_graph *irg, ir_node *node)
190 {
191   irg->cstore = node;
192 }
193
194 ir_node *
195 get_irg_frame (ir_graph *irg)
196 {
197   return irg->frame;
198 }
199
200 void
201 set_irg_frame (ir_graph *irg, ir_node *node)
202 {
203   irg->frame = node;
204 }
205
206 ir_node *
207 get_irg_globals (ir_graph *irg)
208 {
209   return irg->globals;
210 }
211
212 void
213 set_irg_globals (ir_graph *irg, ir_node *node)
214 {
215   irg->globals = node;
216 }
217
218 ir_node *
219 get_irg_args (ir_graph *irg)
220 {
221   return irg->args;
222 }
223
224 void
225 set_irg_args (ir_graph *irg, ir_node *node)
226 {
227   irg->args = node;
228 }
229
230 ir_node *
231 get_irg_bad (ir_graph *irg)
232 {
233   return irg->bad;
234 }
235
236 void
237 set_irg_bad (ir_graph *irg, ir_node *node)
238 {
239   irg->bad = node;
240 }
241
242 ir_node *
243 get_irg_current_block (ir_graph *irg)
244 {
245   return irg->current_block;
246 }
247
248 void
249 set_irg_current_block (ir_graph *irg, ir_node *node)
250 {
251   irg->current_block = node;
252 }
253
254 entity *
255 get_irg_ent (ir_graph *irg)
256 {
257   assert(irg && irg->ent);
258   return irg->ent;
259 }
260
261 void
262 set_irg_ent (ir_graph *irg, entity *ent)
263 {
264   irg->ent = ent;
265 }
266
267 int
268 get_irg_n_loc (ir_graph *irg)
269 {
270   return irg->n_loc;
271 }
272
273 void
274 set_irg_n_loc (ir_graph *irg, int n_loc)
275 {
276   irg->n_loc = n_loc;
277 }
278
279 unsigned long
280 get_irg_visited (ir_graph *irg)
281 {
282   return irg->visited;
283 }
284
285 void
286 set_irg_visited (ir_graph *irg, unsigned long visited)
287 {
288   irg->visited = visited;
289 }
290
291 void
292 inc_irg_visited (ir_graph *irg)
293 {
294   irg->visited = irg->visited++;
295 }
296
297 unsigned long
298 get_irg_block_visited (ir_graph *irg)
299 {
300   return irg->block_visited;
301 }
302
303 void
304 set_irg_block_visited (ir_graph *irg, unsigned long visited)
305 {
306   irg->block_visited = visited;
307 }
308
309 void
310 inc_irg_block_visited (ir_graph *irg)
311 {
312   irg->block_visited = irg->block_visited++;
313 }