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