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