*** 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.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 numbering
54                                       for optimizing use in iropt.c */
55
56   /** Type inforamtion for the procedure of the graph **/
57   res->ent = ent;
58   ent->irg = res;
59
60   /** Nodes needed in every graph **/
61   res->end_block = new_Block ();
62   res->end       = new_End ();
63
64   res->start_block = new_Block ();
65   res->start   = new_Start ();
66   res->bad     = new_ir_node (res, res->start_block, op_Bad, mode_T, 0, NULL);
67
68   /* Proj results of start node */
69   projX        = new_Proj (res->start, mode_X, pns_initial_exec);
70   set_store (new_Proj (res->start, mode_M, pns_global_store));
71   res->frame   = new_Proj (res->start, mode_p, pns_frame_base);
72   res->globals = new_Proj (res->start, mode_p, pns_globals);
73   res->args    = new_Proj (res->start, mode_T, pns_args);
74
75   add_in_edge(res->start_block, projX);
76   // The code generation needs it. leave it in now.
77   // Use of this edge is matter of discussion, unresolved. Also possible:
78   // add_in_edge(res->start_block, res->start_block), but invalid typed.
79
80   mature_block (res->current_block);
81
82   /** Make a block to start with **/
83   first_block = new_Block ();
84   add_in_edge (first_block, projX);
85
86   return res;
87 }
88
89 /* access routines for all ir_graph attributes:
90    templates:
91    {attr type} get_irg_{attribute name} (ir_graph *irg);
92    void set_irg_{attr name} (ir_graph *irg, {attr type} {attr}); */
93
94 ir_node *
95 get_irg_start_block (ir_graph *irg)
96 {
97   return irg->start_block;
98 }
99
100 void
101 set_irg_start_block (ir_graph *irg, ir_node *node)
102 {
103   irg->start_block = node;
104 }
105
106 ir_node *
107 get_irg_start (ir_graph *irg)
108 {
109   return irg->start;
110 }
111
112 void
113 set_irg_start(ir_graph *irg, ir_node *node)
114 {
115   irg->start = node;
116 }
117
118 ir_node *
119 get_irg_end_block (ir_graph *irg)
120 {
121   return irg->end_block;
122 }
123
124 void
125 set_irg_end_block (ir_graph *irg, ir_node *node)
126 {
127   irg->end_block = node;
128 }
129
130 ir_node *
131 get_irg_end (ir_graph *irg)
132 {
133   return irg->end;
134 }
135
136 void
137 set_irg_end (ir_graph *irg, ir_node *node)
138 {
139   irg->end = node;
140 }
141
142 ir_node *
143 get_irg_cstore (ir_graph *irg)
144 {
145   return irg->cstore;
146 }
147
148 void
149 set_irg_cstore (ir_graph *irg, ir_node *node)
150 {
151   irg->cstore = node;
152 }
153
154 ir_node *
155 get_irg_frame (ir_graph *irg)
156 {
157   return irg->frame;
158 }
159
160 void
161 set_irg_frame (ir_graph *irg, ir_node *node)
162 {
163   irg->frame = node;
164 }
165
166 ir_node *
167 get_irg_globals (ir_graph *irg)
168 {
169   return irg->globals;
170 }
171
172 void
173 set_irg_globals (ir_graph *irg, ir_node *node)
174 {
175   irg->globals = node;
176 }
177
178 ir_node *
179 get_irg_args (ir_graph *irg)
180 {
181   return irg->args;
182 }
183
184 void
185 set_irg_args (ir_graph *irg, ir_node *node)
186 {
187   irg->args = node;
188 }
189
190 ir_node *
191 get_irg_bad (ir_graph *irg)
192 {
193   return irg->bad;
194 }
195
196 void
197 set_irg_bad (ir_graph *irg, ir_node *node)
198 {
199   irg->bad = node;
200 }
201
202 ir_node *
203 get_irg_current_block (ir_graph *irg)
204 {
205   return irg->current_block;
206 }
207
208 void
209 set_irg_current_block (ir_graph *irg, ir_node *node)
210 {
211   irg->current_block = node;
212 }
213
214 entity *
215 get_irg_ent (ir_graph *irg)
216 {
217   return irg->ent;
218 }
219
220 void
221 set_irg_ent (ir_graph *irg, entity *ent)
222 {
223   irg->ent = ent;
224 }
225
226 int
227 get_irg_params (ir_graph *irg)
228 {
229   return irg->params;
230 }
231
232 void
233 set_irg_params (ir_graph *irg, int params)
234 {
235   irg->params = params;
236 }
237
238 unsigned long
239 get_irg_visited (ir_graph *irg)
240 {
241   return irg->visited;
242 }
243
244 void
245 set_irg_visited (ir_graph *irg, unsigned long visited)
246 {
247   irg->visited = visited;
248 }
249
250 void
251 inc_irg_visited (ir_graph *irg)
252 {
253   irg->visited = irg->visited++;
254 }
255
256 unsigned long
257 get_irg_block_visited (ir_graph *irg)
258 {
259   return irg->block_visited;
260 }
261
262 void
263 set_irg_block_visited (ir_graph *irg, unsigned long visited)
264 {
265   irg->block_visited = visited;
266 }
267
268 void
269 inc_irg_block_visited (ir_graph *irg)
270 {
271   irg->block_visited = irg->block_visited++;
272 }