removed warnings
[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 <string.h>
16
17 # include "ircons.h"
18 # include "irgraph_t.h"
19 # include "irprog_t.h"
20 # include "iropt_t.h"
21 # include "array.h"
22 # include "irgmod.h"
23 # include "mangle.h"
24
25 ir_graph *current_ir_graph;
26 INLINE ir_graph *get_current_ir_graph() {
27   return current_ir_graph;
28 }
29 INLINE void set_current_ir_graph(ir_graph *graph) {
30   current_ir_graph = graph;
31 }
32
33
34 bool interprocedural_view = false;
35 INLINE bool get_interprocedural_view() {
36   return interprocedural_view;
37 }
38 INLINE void set_interprocedural_view(bool state) {
39   interprocedural_view = state;
40 }
41
42 #if USE_EXPLICIT_PHI_IN_STACK
43 /* really defined in ircons.c */
44 typedef struct Phi_in_stack Phi_in_stack;
45 Phi_in_stack *new_Phi_in_stack();
46 void free_Phi_in_stack(Phi_in_stack *s);
47 #endif
48
49 /* Allocates a list of nodes:
50     - The start block containing a start node and Proj nodes for it's four
51       results (X, M, P, Tuple).
52     - The end block containing an end node. This block is not matured after
53       new_ir_graph as predecessors need to be added to it.
54     - The current block, which is empty and also not matured.
55    Further it allocates several datastructures needed for graph construction
56    and optimization.
57 */
58 ir_graph *
59 new_ir_graph (entity *ent, int n_loc)
60 {
61   ir_graph *res;
62   ir_node *first_block;
63   ir_node *projX;
64
65   res = (ir_graph *) malloc (sizeof (ir_graph));
66   current_ir_graph = res;
67   add_irp_irg(res);          /* remember this graph global. */
68
69 /**
70   * initialized for each graph. **/
71 #if PRECISE_EXC_CONTEXT
72   res->n_loc = n_loc + 1 + 1; /* number of local variables that are never
73                                  dereferenced in this graph plus one for
74                                  the store plus one for links to fragile
75                                  operations.  n_loc is not the number of
76                                  parameters to the procedure!  */
77 #else
78   res->n_loc = n_loc + 1;  /* number of local variables that are never
79                               dereferenced in this graph plus one for
80                               the store. This is not the number of parameters
81                               to the procedure!  */
82 #endif
83
84   res->visited = 0;     /* visited flag, for the ir walker */
85   res->block_visited=0; /* visited flag, for the 'block'-walker */
86
87 #if USE_EXPLICIT_PHI_IN_STACK
88   res->Phi_in_stack = new_Phi_in_stack();  /* A stack needed for automatic Phi
89                                 generation */
90 #endif
91   res->obst      = (struct obstack *) xmalloc (sizeof (struct obstack));
92   obstack_init (res->obst);
93   res->value_table = new_identities (); /* value table for global value
94                                            numbering for optimizing use in
95                                            iropt.c */
96   res->outs = NULL;
97
98   res->phase_state = phase_building;
99   res->pinned = pinned;
100   res->outs_state = no_outs;
101   res->dom_state = no_dom;
102
103   /** Type information for the procedure of the graph **/
104   res->ent = ent;
105   set_entity_irg(ent, res);
106
107 /**
108       contain "inner" methods as in Pascal. **/
109   res->frame_type = new_type_class(mangle(get_entity_ident(ent),
110           id_from_str(FRAME_TP_SUFFIX, strlen(FRAME_TP_SUFFIX))));
111   /* Remove type from type list.  Must be treated differently than other types. */
112   remove_irp_type_from_list(res->frame_type);
113
114   /** Nodes needed in every graph **/
115   res->end_block = new_immBlock ();
116   res->end       = new_End ();
117
118   res->start_block = new_immBlock ();
119   res->start   = new_Start ();
120   res->bad     = new_ir_node (NULL, res, res->start_block, op_Bad, mode_T, 0, NULL);
121   res->unknown = new_ir_node (NULL, res, res->start_block, op_Unknown, mode_T, 0, NULL);
122
123   /* Proj results of start node */
124   projX        = new_Proj (res->start, mode_X, pns_initial_exec);
125   set_store (new_Proj (res->start, mode_M, pns_global_store));
126   res->frame   = new_Proj (res->start, mode_P, pns_frame_base);
127   res->globals = new_Proj (res->start, mode_P, pns_globals);
128   res->args    = new_Proj (res->start, mode_T, pns_args);
129
130   add_in_edge(res->start_block, projX);
131   /*
132    * The code generation needs it. leave it in now.
133    * Use of this edge is matter of discussion, unresolved. Also possible:
134    * add_in_edge(res->start_block, res->start_block), but invalid typed.
135    */
136   mature_block (res->current_block);
137
138   /** Make a block to start with **/
139   first_block = new_immBlock ();
140   add_in_edge (first_block, projX);
141
142   return res;
143 }
144
145
146 /* Make a rudimentary ir graph for the constant code.
147    Must look like a correct irg, spare everything else. */
148 ir_graph *new_const_code_irg() {
149   ir_graph *res;
150   ir_node *projX;
151
152   res = (ir_graph *) malloc (sizeof (ir_graph));
153   current_ir_graph = res;
154   res->n_loc = 1;      /* Only the memory. */
155   res->visited = 0;     /* visited flag, for the ir walker */
156   res->block_visited=0; /* visited flag, for the 'block'-walker */
157 #if USE_EXPLICIT_PHI_IN_STACK
158   res->Phi_in_stack = NULL;
159 #endif
160   res->obst      = (struct obstack *) xmalloc (sizeof (struct obstack));
161   obstack_init (res->obst);
162   res->phase_state = phase_building;
163   res->pinned = pinned;
164   res->value_table = new_identities (); /* value table for global value
165                                            numbering for optimizing use in
166                                            iropt.c */
167   res->ent = NULL;
168   res->frame_type = NULL;
169   res->start_block = new_immBlock ();
170   res->end_block = new_immBlock ();
171   res->end       = new_End ();
172   mature_block(get_cur_block());
173   res->bad = new_ir_node (NULL, res, res->start_block, op_Bad, mode_T, 0, NULL);
174   res->unknown = new_ir_node (NULL, res, res->start_block, op_Unknown, mode_T, 0, NULL);
175   res->start   = new_Start ();
176   /* Proj results of start node */
177   projX        = new_Proj (res->start, mode_X, pns_initial_exec);
178   set_store (new_Proj (res->start, mode_M, pns_global_store));
179   add_in_edge(res->start_block, projX);
180   mature_block (res->current_block);
181   add_in_edge (new_immBlock (), projX);
182   mature_block(get_cur_block());
183   /* Set the visited flag high enough that the block will never be visited. */
184   set_irn_visited(get_cur_block(), -1);
185   set_Block_block_visited(get_cur_block(), -1);
186   set_Block_block_visited(res->start_block, -1);
187   return res;
188 }
189
190 /* Frees the passed irgraph.
191    Deallocates all nodes in this graph and the ir_graph structure.
192    Sets the field irgraph in the corresponding entity to NULL.
193    Does not remove the irgraph from the list in irprog (requires
194    inefficient search, call remove_irp_irg by hand).
195    Does not free types, entities or modes that are used only by this
196    graph, nor the entity standing for this graph. */
197 void free_ir_graph (ir_graph *irg) {
198   set_entity_irg(irg->ent, NULL);
199   free(irg->obst);
200 #if USE_EXPLICIT_PHI_IN_STACK
201   free_Phi_in_stack(irg->Phi_in_stack);
202 #endif
203   free(irg);
204 }
205
206 /* access routines for all ir_graph attributes:
207    templates:
208    {attr type} get_irg_{attribute name} (ir_graph *irg);
209    void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
210
211 ir_node *
212 get_irg_start_block (ir_graph *irg)
213 {
214   return irg->start_block;
215 }
216
217 void
218 set_irg_start_block (ir_graph *irg, ir_node *node)
219 {
220   irg->start_block = node;
221 }
222
223 ir_node *
224 get_irg_start (ir_graph *irg)
225 {
226   return irg->start;
227 }
228
229 void
230 set_irg_start(ir_graph *irg, ir_node *node)
231 {
232   irg->start = node;
233 }
234
235 ir_node *
236 get_irg_end_block (ir_graph *irg)
237 {
238   return irg->end_block;
239 }
240
241 void
242 set_irg_end_block (ir_graph *irg, ir_node *node)
243 {
244   irg->end_block = node;
245 }
246
247 ir_node *
248 get_irg_end (ir_graph *irg)
249 {
250   return irg->end;
251 }
252
253 void
254 set_irg_end (ir_graph *irg, ir_node *node)
255 {
256   irg->end = node;
257 }
258
259 ir_node *
260 get_irg_cstore (ir_graph *irg)
261 {
262   return irg->cstore;
263 }
264
265 void
266 set_irg_cstore (ir_graph *irg, ir_node *node)
267 {
268   irg->cstore = node;
269 }
270
271 ir_node *
272 get_irg_frame (ir_graph *irg)
273 {
274   return irg->frame;
275 }
276
277 void
278 set_irg_frame (ir_graph *irg, ir_node *node)
279 {
280   irg->frame = node;
281 }
282
283 ir_node *
284 get_irg_globals (ir_graph *irg)
285 {
286   return irg->globals;
287 }
288
289 void
290 set_irg_globals (ir_graph *irg, ir_node *node)
291 {
292   irg->globals = node;
293 }
294
295 ir_node *
296 get_irg_args (ir_graph *irg)
297 {
298   return irg->args;
299 }
300
301 void
302 set_irg_args (ir_graph *irg, ir_node *node)
303 {
304   irg->args = node;
305 }
306
307 ir_node *
308 get_irg_bad (ir_graph *irg)
309 {
310   return irg->bad;
311 }
312
313 void
314 set_irg_bad (ir_graph *irg, ir_node *node)
315 {
316   irg->bad = node;
317 }
318
319 ir_node *
320 get_irg_unknown (ir_graph *irg)
321 {
322   return irg->unknown;
323 }
324
325 void
326 set_irg_unknown (ir_graph *irg, ir_node *node)
327 {
328   irg->unknown = node;
329 }
330
331 ir_node *
332 get_irg_current_block (ir_graph *irg)
333 {
334   return irg->current_block;
335 }
336
337 void
338 set_irg_current_block (ir_graph *irg, ir_node *node)
339 {
340   irg->current_block = node;
341 }
342
343 entity *
344 get_irg_ent (ir_graph *irg)
345 {
346   assert(irg && irg->ent);
347   return irg->ent;
348 }
349
350 void
351 set_irg_ent (ir_graph *irg, entity *ent)
352 {
353   irg->ent = ent;
354 }
355
356 type *
357 get_irg_frame_type (ir_graph *irg)
358 {
359   assert(irg && irg->frame_type);
360   return irg->frame_type;
361 }
362
363 void
364 set_irg_frame_type (ir_graph *irg, type *ftp)
365 {
366   irg->frame_type = ftp;
367 }
368
369
370 /* To test for a frame type */
371 int
372 is_frame_type(type *ftp) {
373   return ((is_class_type(ftp) || is_struct_type(ftp)) &&
374           id_is_suffix(id_from_str(FRAME_TP_SUFFIX, strlen(FRAME_TP_SUFFIX)),
375                        get_type_ident(ftp)));
376 }
377
378 int
379 get_irg_n_locs (ir_graph *irg)
380 {
381 #if PRECISE_EXC_CONTEXT
382   return irg->n_loc - 1 - 1;
383 #else
384   return irg->n_loc - 1;
385 #endif
386 }
387
388 void
389 set_irg_n_loc (ir_graph *irg, int n_loc)
390 {
391 #if PRECISE_EXC_CONTEXT
392   irg->n_loc = n_loc + 1 + 1;
393 #else
394   irg->n_loc = n_loc + 1;
395 #endif
396 }
397
398 irg_phase_state
399 get_irg_phase_state (ir_graph *irg) {
400   return irg->phase_state;
401 }
402
403 void
404 set_irg_phase_low(ir_graph *irg) {
405   irg->phase_state = phase_low;
406 }
407
408 op_pinned
409 get_irg_pinned (ir_graph *irg) {
410   return irg->pinned;
411 }
412
413 irg_outs_state
414 get_irg_outs_state(ir_graph *irg) {
415   return irg->outs_state;
416 }
417
418 void
419 set_irg_outs_inconsistent(ir_graph *irg) {
420   irg->outs_state = outs_inconsistent;
421 }
422
423 irg_dom_state
424 get_irg_dom_state(ir_graph *irg) {
425   return irg->dom_state;
426 }
427
428 void
429 set_irg_dom_inconsistent(ir_graph *irg) {
430   irg->dom_state = dom_inconsistent;
431 }
432
433 INLINE void
434 set_irg_pinned (ir_graph *irg, op_pinned p) {
435   irg->pinned = p;
436 }
437
438 INLINE void
439 set_irg_link (ir_graph *irg, void *thing) {
440   irg->link = thing;
441 }
442
443 INLINE void *
444 get_irg_link (ir_graph *irg) {
445   return irg->link;
446 }
447
448 /* maximum visited flag content of all ir_graph visited fields. */
449 static int max_irg_visited = 0;
450
451 unsigned long
452 get_irg_visited (ir_graph *irg)
453 {
454   return irg->visited;
455 }
456
457 void
458 set_irg_visited (ir_graph *irg, unsigned long visited)
459 {
460   irg->visited = visited;
461   if (irg->visited > max_irg_visited) {
462     max_irg_visited = irg->visited;
463   }
464 }
465
466 void
467 inc_irg_visited (ir_graph *irg)
468 {
469   if (++irg->visited > max_irg_visited) {
470     max_irg_visited = irg->visited;
471   }
472 }
473
474 unsigned long
475 get_max_irg_visited(void)
476 {
477   //int i;
478   //for(i = 0; i < get_irp_n_irgs(); i++)
479   //  assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
480   return max_irg_visited;
481 }
482
483 void set_max_irg_visited(int val) {
484   max_irg_visited = val;
485 }
486
487 unsigned long
488 inc_max_irg_visited(void)
489 {
490   //int i;
491   //  for(i = 0; i < get_irp_n_irgs(); i++)
492   //assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
493   max_irg_visited++;
494   return max_irg_visited;
495 }
496
497 unsigned long
498 get_irg_block_visited (ir_graph *irg)
499 {
500   return irg->block_visited;
501 }
502
503 void
504 set_irg_block_visited (ir_graph *irg, unsigned long visited)
505 {
506   irg->block_visited = visited;
507 }
508
509 void
510 inc_irg_block_visited (ir_graph *irg)
511 {
512   ++irg->block_visited;
513 }