Bugfixes
[libfirm] / ir / ana2 / pto_init.c
1 /* -*- c -*- */
2
3 /*
4    Project:     libFIRM
5    File name:   ir/ana/pto_init.c
6    Purpose:     Initialisation Functions
7    Author:      Florian
8    Modified by:
9    Created:     Sat Nov 13 19:35:27 CET 2004
10    CVS-ID:      $Id$
11    Copyright:   (c) 1999-2004 Universität Karlsruhe
12    Licence:     This file is protected by the GPL -  GNU GENERAL PUBLIC LICENSE.
13 */
14
15 # ifdef HAVE_CONFIG_H
16 #  include <config.h>
17 # endif
18
19 /*
20  pto_init: Initialisation Functions
21 */
22
23 # include <obstack.h>
24 # include <string.h>
25
26 # include "pto.h"
27 # include "pto_init.h"
28 # include "pto_debug.h"
29 # include "pto_comp.h"
30 # include "pto_name.h"
31 # include "pto_util.h"
32
33 # include "typewalk.h"
34 # include "irgwalk.h"
35 # include "xmalloc.h"
36
37 /* Local Defines: */
38 # define obstack_chunk_alloc xmalloc
39 # define obstack_chunk_free  free
40
41 /* Local Data Types: */
42 typedef struct init_env_str
43 {
44   int n_ctxs;
45 } init_env_t;
46
47 typedef struct reset_env_str
48 {
49   int ctx_idx;
50 } reset_env_t;
51
52 /* Local Variables: */
53 extern struct obstack *qset_obst; /* from pto_name */
54
55 static struct obstack *pto_obst = NULL; /* all pto_t's go onto this one */
56
57 /* Local Prototypes: */
58
59 /* ===================================================
60    Local Implementation:
61    =================================================== */
62 /* Allocate a new pto */
63 static pto_t *new_pto (ir_node *node)
64 {
65   pto_t *pto = obstack_alloc (pto_obst, sizeof (pto_t));
66   pto->values = qset_new (N_INITIAL_OJBS, qset_obst);
67
68   return (pto);
69 }
70
71 /* Allocate a new alloc_pto */
72 static alloc_pto_t *new_alloc_pto (ir_node *alloc, int n_ctxs)
73 {
74   assert (iro_Alloc == get_irn_opcode (alloc));
75
76   int i;
77   alloc_pto_t *alloc_pto = obstack_alloc (pto_obst, sizeof (alloc_pto_t));
78   type *tp = get_Alloc_type (alloc);
79
80   alloc_pto->ptos = (pto_t**) obstack_alloc (pto_obst, n_ctxs * sizeof (pto_t*));
81
82   for (i = 0; i < n_ctxs; i ++) {
83     desc_t *desc = new_name (tp, alloc);
84     alloc_pto->ptos [i] = new_pto (alloc);
85     qset_insert (alloc_pto->ptos [i]->values, desc);
86   }
87
88   return (alloc_pto);
89 }
90
91 /* Allocate a new pto for a symconst */
92 static pto_t* new_symconst_pto (ir_node *symconst)
93 {
94   assert (iro_SymConst == get_irn_opcode (symconst));
95
96   pto_t *pto = new_pto (symconst);
97   entity *ent = get_SymConst_entity (symconst);
98   desc_t *desc = new_ent_name (ent);
99
100   qset_insert (pto->values, desc);
101
102   return (pto);
103 }
104
105 /* Helper to pto_init --- clear the link fields of class types */
106 static void clear_type_link (type_or_ent *thing, void *__unused)
107 {
108   if (is_type (thing)) {
109     type *tp = (type*) thing;
110
111     if (is_class_type (tp)) {
112       DBGPRINT (1, (stdout, "%s (\"%s\")\n",
113                     __FUNCTION__, get_type_name (tp)));
114
115       set_type_link (tp, NULL);
116     }
117   } else if (is_entity (thing)) {
118     entity *ent = (entity*) thing;
119
120     DBGPRINT (1, (stdout, "%s (\"%s\")\n",
121                   __FUNCTION__, get_entity_name (ent)));
122
123     set_entity_link (ent, NULL);
124   }
125 }
126
127 /* Helper to pto_init_graph --- clear the links of the given node */
128 static void clear_node_link (ir_node *node, void *__unused)
129 {
130   set_irn_link (node, NULL);
131 }
132
133 /* Helper to pto_init_graph --- clear the links of all nodes */
134 static void clear_graph_links (ir_graph *graph)
135 {
136   irg_walk_graph (graph, clear_node_link, NULL, NULL);
137 }
138
139 /* Reset ALL the pto values for a new pass */
140 static void reset_node_pto (ir_node *node, void *env)
141 {
142   reset_env_t *reset_env = (reset_env_t*) env;
143   int ctx_idx = reset_env->ctx_idx;
144   const opcode op = get_irn_opcode (node);
145
146   switch (op) {
147   case (iro_Load):
148   case (iro_SymConst):
149   case (iro_Const):
150   case (iro_Call):
151   case (iro_Phi): {
152     /* allocate 'empty' pto values */
153     pto_t *pto = new_pto (node);
154     set_node_pto (node, pto);
155     } break;
156
157   case (iro_Alloc): {
158     /* set alloc to 'right' current pto */
159     alloc_pto_t *alloc_pto = (alloc_pto_t*) get_irn_link (node);
160     alloc_pto->curr_pto = alloc_pto->ptos [ctx_idx];
161     } break;
162
163   default: {
164     /* nothing */
165   } break;
166   }
167 }
168
169 /* Temporary fix until we get 'real' ptos: Allocate some dummy for pto */
170 static void init_pto (ir_node *node, void *env)
171 {
172   init_env_t *init_env = (init_env_t*) env;
173   int n_ctxs = init_env->n_ctxs;
174
175   const opcode op = get_irn_opcode (node);
176
177   switch (op) {
178   case (iro_SymConst): {
179     const symconst_kind kind = get_SymConst_kind (node);
180
181     if ((kind == symconst_addr_name) || (kind == symconst_addr_ent)) {
182       entity *ent = get_SymConst_entity (node);
183
184       if (is_pointer_type (get_entity_type (ent))) {
185         DBGPRINT (0, (stdout, "%s: new name \"%s\" for symconst \"%s[%li]\"\n",
186                       __FUNCTION__,
187                       get_entity_name (ent),
188                       OPNAME (node),
189                       OPNUM (node)));
190
191         pto_t *symconst_pto = new_symconst_pto (node);
192         set_node_pto (node, symconst_pto);
193       }
194     }
195   } break;
196   case (iro_Alloc): {
197     type *tp = get_Alloc_type (node); /* debugging only */
198     alloc_pto_t *alloc_pto = new_alloc_pto (node, n_ctxs);
199     set_alloc_pto (node, alloc_pto);
200
201     DBGPRINT (0, (stdout, "%s: %i names \"%s\" for alloc \"%s[%li]\"\n",
202                   __FUNCTION__,
203                   n_ctxs,
204                   get_type_name (tp),
205                   OPNAME (node),
206                   OPNUM (node)));
207   } break;
208
209   case (iro_Load):
210   case (iro_Call):
211   case (iro_Phi):
212   case (iro_Const):
213     /* nothing --- handled by reset_node_pto on each pass */
214     break;
215   default: {
216     /* nothing */
217   } break;
218   }
219 }
220
221
222 /* Initialise the given graph for a new pass run */
223 static void pto_init_graph_allocs (ir_graph *graph)
224 {
225   graph_info_t *ginfo = ecg_get_info (graph);
226   int n_ctxs = ginfo->n_ctxs;
227
228   init_env_t *init_env = xmalloc (sizeof (init_env_t));
229   init_env->n_ctxs = n_ctxs;
230
231   HERE ("start");
232
233   irg_walk_graph (graph, init_pto, NULL, init_env);
234
235   memset (init_env, 0x00, sizeof (init_env_t));
236   free (init_env);
237
238   HERE ("end");
239 }
240
241 /* ===================================================
242    Exported Implementation:
243    =================================================== */
244 /* "Fake" the arguments to the main method */
245 void fake_main_args (ir_graph *graph)
246 {
247   HERE ("start");
248
249   entity *ent = get_irg_entity (graph);
250   type *mtp = get_entity_type (ent);
251   ir_node **args = find_irg_args (graph);
252   type *ctp = get_method_param_type (mtp, 1); /* ctp == char[]*[]* */
253
254   /* 'main' has signature 'void(int, char[]*[]*)' */
255   assert (NULL == args [2]);
256
257   assert (is_pointer_type (ctp));
258
259   ctp = get_pointer_points_to_type (ctp); /* ctp == char[]*[] */
260
261   assert (is_array_type (ctp));
262
263   desc_t *arg_desc = new_name (ctp, args [1]);
264   pto_t *arg_pto = new_pto (args [1]);
265   /* todo: simulate 'store' to arg1[] ?!? */
266   qset_insert (arg_pto->values, arg_desc);
267
268   set_node_pto (args [1], arg_pto);
269
270 # ifdef TEST_MAIN_TYPE
271   ctp = get_array_element_type (ctp); /* ctp == char[]* */
272
273   assert (is_pointer_type (ctp));
274
275   ctp = get_pointer_points_to_type (ctp); /* ctp == char[] */
276
277   assert (is_array_type (ctp));
278
279   ctp = get_array_element_type (ctp); /* ctp == char */
280
281   assert (is_primitive_type (ctp));
282 # endif /* defined  TEST_MAIN_TYPE */
283
284   HERE ("end");
285 }
286
287 /* Initialise the Init module */
288 void pto_init_init ()
289 {
290   pto_obst = (struct obstack*) xmalloc (sizeof (struct obstack));
291
292   obstack_init (pto_obst);
293 }
294
295 /* Cleanup the Init module */
296 void pto_init_cleanup ()
297 {
298   obstack_free (pto_obst, NULL);
299   memset (pto_obst, 0x00, sizeof (struct obstack));
300   free (pto_obst);
301   pto_obst = NULL;
302 }
303
304
305 /* Initialise the Names of the Types/Entities */
306 void pto_init_type_names ()
307 {
308   HERE ("start");
309   type_walk (clear_type_link, NULL, NULL);
310   HERE ("end");
311 }
312
313 /* Initialise the given graph for a new pass run */
314 void pto_init_graph (ir_graph *graph)
315 {
316   graph_info_t *ginfo = ecg_get_info (graph);
317   const int n_ctxs = ginfo->n_ctxs;
318
319   /* only for debugging stuff: */
320   entity *ent = get_irg_entity (graph);
321   const char *ent_name = (char*) get_entity_name (ent);
322   const char *own_name = (char*) get_type_name (get_entity_owner (ent));
323
324   DBGPRINT (0, (stdout, "%s: init \"%s.%s\" for %i ctxs\n", __FUNCTION__,
325                 own_name, ent_name, n_ctxs));
326
327   HERE ("start");
328
329   clear_graph_links     (graph);
330   pto_init_graph_allocs (graph);
331
332   HERE ("end");
333 }
334
335 /* Reset the given graph for a new pass run */
336 void pto_reset_graph_pto (ir_graph *graph, int ctx_idx)
337 {
338   HERE ("start");
339
340   reset_env_t *reset_env = (reset_env_t*) xmalloc (sizeof (reset_env_t));
341   reset_env->ctx_idx = ctx_idx;
342
343   irg_walk_graph (graph, reset_node_pto, NULL, reset_env);
344
345   memset (reset_env, 0x00, sizeof (reset_env_t));
346   free (reset_env);
347   HERE ("end");
348 }
349
350 \f
351 /*
352   $Log$
353   Revision 1.5  2004/11/24 14:53:56  liekweg
354   Bugfixes
355
356   Revision 1.4  2004/11/20 21:21:56  liekweg
357   Finalise initialisation
358
359   Revision 1.3  2004/11/18 16:37:07  liekweg
360   rewrite
361
362
363 */