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