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