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