some .cvsignore files
[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 "tv.h"
36 # include "xmalloc.h"
37
38 # include "gnu_ext.h"
39
40 /* Local Defines: */
41 # define obstack_chunk_alloc xmalloc
42 # define obstack_chunk_free  free
43
44 /* Local Data Types: */
45 typedef struct init_env_str
46 {
47   int n_ctxs;
48 } init_env_t;
49
50 typedef struct reset_env_str
51 {
52   int ctx_idx;
53 } reset_env_t;
54
55 /* Local Variables: */
56 extern struct obstack *qset_obst; /* from pto_name */
57
58 static struct obstack *pto_obst = NULL; /* all pto_t's go onto this one */
59
60 /* Local Prototypes: */
61
62 /* ===================================================
63    Local Implementation:
64    =================================================== */
65 /** Allocate a new pto */
66 static pto_t *new_pto (ir_node *node)
67 {
68   pto_t *pto = obstack_alloc (pto_obst, sizeof (pto_t));
69   pto->values = qset_new (N_INITIAL_OJBS, qset_obst);
70
71   return (pto);
72 }
73
74 /** Allocate a new alloc_pto */
75 static alloc_pto_t *new_alloc_pto (ir_node *alloc, int n_ctxs)
76 {
77   int i;
78   alloc_pto_t *alloc_pto = obstack_alloc (pto_obst, sizeof (alloc_pto_t));
79   type *tp;
80
81   assert (op_Alloc == get_irn_op(alloc));
82
83   tp = get_Alloc_type (alloc);
84
85   alloc_pto->ptos = (pto_t**) obstack_alloc (pto_obst, n_ctxs * sizeof (pto_t*));
86
87   for (i = 0; i < n_ctxs; i ++) {
88     desc_t *desc = new_name (tp, alloc, i);
89     alloc_pto->ptos [i] = new_pto (alloc);
90     qset_insert (alloc_pto->ptos [i]->values, desc);
91   }
92
93   return (alloc_pto);
94 }
95
96 /** Allocate a new pto for a symconst */
97 static pto_t* new_symconst_pto (ir_node *symconst)
98 {
99   pto_t *pto;
100   entity *ent;
101   desc_t *desc = NULL;
102
103   assert (op_SymConst == get_irn_op(symconst));
104
105   pto = new_pto (symconst);
106   ent = get_SymConst_entity (symconst);
107
108   /*
109   const char *ent_name = (char*) get_entity_name (ent);
110   const char *own_name = (char*) get_type_name (get_entity_owner (ent));
111   HERE3 ("start", own_name, ent_name);
112   */
113   /* Ok, so if the symconst has a pointer-to-mumble, it's some address
114      calculation, but if it's the mumble itself, it's just the same,
115      except it's presumably a constant of mumble. In any case, we need to
116      branch on this.  "How's that for object fucking oriented? --jwz" */
117   if (is_Pointer_type (get_entity_type (ent))) {
118     desc = new_ent_name (ent);
119   } else if (is_Class_type (get_entity_type (ent))) {
120     desc = new_name (get_entity_type (ent), symconst, -1);
121   } else {
122     fprintf (stderr, "%s: not handled: %s[%li] (\"%s\")\n",
123              __FUNCTION__,
124              get_op_name (get_irn_op (symconst)),
125              get_irn_node_nr (symconst),
126              get_entity_name (ent));
127     assert (0 && "something not handled");
128   }
129
130   qset_insert (pto->values, desc);
131
132   /* HERE3 ("end", own_name, ent_name); */
133
134   return (pto);
135 }
136
137 /* Helper to pto_init --- clear the link fields of class types */
138 static void clear_type_link (type_or_ent *thing, void *_unused)
139 {
140   if (is_type (thing)) {
141     type *tp = (type*) thing;
142
143     if (is_Class_type (tp)) {
144       DBGPRINT (1, (stdout, "%s (\"%s\")\n",
145                     __FUNCTION__,
146                     get_type_name (tp)));
147
148       set_type_link (tp, NULL);
149     }
150   } else if (is_entity (thing)) {
151     entity *ent = (entity*) thing;
152
153     DBGPRINT (1, (stdout, "%s (\"%s\")\n",
154                   __FUNCTION__,
155                   get_entity_name (ent)));
156
157     set_entity_link (ent, NULL);
158   }
159 }
160
161 /** Helper to pto_init_graph --- clear the links of the given node */
162 static void clear_node_link (ir_node *node, void *_unused)
163 {
164   set_irn_link (node, NULL);
165 }
166
167 /** Helper to pto_init_graph --- clear the links of all nodes */
168 static void clear_graph_links (ir_graph *graph)
169 {
170   irg_walk_graph (graph, clear_node_link, NULL, NULL);
171 }
172
173 /** Reset ALL the pto values for a new pass */
174 static void reset_node_pto (ir_node *node, void *env)
175 {
176   reset_env_t *reset_env = (reset_env_t*) env;
177   int ctx_idx = reset_env->ctx_idx;
178   opcode op = get_irn_opcode (node);
179
180   /* HERE ("start"); */
181
182   switch (op) {
183   case (iro_Load):
184   case (iro_Call):
185   case (iro_Block):             /* END BLOCK only */
186   case (iro_Phi): {
187     /* allocate 'empty' pto values */
188     pto_t *pto = new_pto (node);
189     set_node_pto (node, pto);
190   } break;
191
192   case (iro_Alloc): {
193     /* set alloc to 'right' current pto */
194     alloc_pto_t *alloc_pto = (alloc_pto_t*) get_irn_link (node);
195     alloc_pto->curr_pto = alloc_pto->ptos [ctx_idx];
196
197     DBGPRINT (1, (stdout, "%s: setting pto of \"%s[%li]\" for ctx %i\n",
198                   __FUNCTION__,
199                   OPNAME (node),
200                   OPNUM (node),
201                   ctx_idx));
202
203     assert (alloc_pto->curr_pto);
204   } break;
205   case (iro_Const):
206   case (iro_SymConst): {
207       /* nothing, leave as-is */
208     } break;
209
210   default: {
211     /* basically, nothing */
212     DBGPRINT (2, (stdout, "%s: resetting pto of \"%s[%li]\"\n",
213                   __FUNCTION__,
214                   OPNAME (node),
215                   OPNUM (node)));
216     set_node_pto (node, NULL);
217   } break;
218   }
219
220   /* HERE ("end"); */
221 }
222
223 /** Initialise primary name sources */
224 static void init_pto (ir_node *node, void *env)
225 {
226   init_env_t *init_env = (init_env_t*) env;
227   int n_ctxs = init_env->n_ctxs;
228
229   opcode op = get_irn_opcode (node);
230
231   switch (op) {
232   case (iro_SymConst): {
233     if (mode_is_reference (get_irn_mode (node))) {
234       entity *ent = get_SymConst_entity (node);
235       type   *tp = get_entity_type (ent);
236       if (is_Class_type (tp) || is_Pointer_type (tp)) {
237         pto_t *symconst_pto = new_symconst_pto (node);
238         set_node_pto (node, symconst_pto);
239
240         /* debugging only */
241         DBGPRINT (1, (stdout, "%s: new name \"%s\" for \"%s[%li]\"\n",
242                       __FUNCTION__,
243                       get_entity_name (ent),
244                       OPNAME (node),
245                       OPNUM (node)));
246       }
247     }
248   } break;
249
250   case (iro_Alloc): {
251     alloc_pto_t *alloc_pto = new_alloc_pto (node, n_ctxs);
252     type *tp;
253
254     set_alloc_pto (node, alloc_pto);
255
256     tp = get_Alloc_type (node); /* debugging only */
257     DBGPRINT (1, (stdout, "%s: %i names \"%s\" for \"%s[%li]\"\n",
258                   __FUNCTION__,
259                   n_ctxs,
260                   get_type_name (tp),
261                   OPNAME (node),
262                   OPNUM (node)));
263   } break;
264
265   case (iro_Const): {
266     tarval *tv = get_Const_tarval (node);
267
268     /* only need 'NULL' pointer constants */
269     if (mode_P == get_tarval_mode (tv)) {
270       if (get_tarval_null (mode_P) == tv) {
271         pto_t *pto = new_pto (node);
272         set_node_pto (node, pto);
273       }
274     }
275   } break;
276   case (iro_Load):
277   case (iro_Call):
278   case (iro_Phi):
279     /* nothing --- handled by reset_node_pto on each pass */
280     break;
281   default: {
282     /* nothing */
283   } break;
284   }
285 }
286
287
288 /** Initialise the given graph for a new pass run */
289 static void pto_init_graph_allocs (ir_graph *graph)
290 {
291   graph_info_t *ginfo = ecg_get_info (graph);
292   init_env_t *init_env;
293
294   init_env = xmalloc (sizeof (init_env_t));
295   init_env->n_ctxs = ginfo->n_ctxs;
296
297   /* HERE ("start"); */
298
299   irg_walk_graph (graph, init_pto, NULL, init_env);
300
301   /* HERE ("end"); */
302   memset (init_env, 0x00, sizeof (init_env_t));
303   free (init_env);
304 }
305
306 /* ===================================================
307    Exported Implementation:
308    =================================================== */
309 /* "Fake" the arguments to the main method */
310 void fake_main_args (ir_graph *graph)
311 {
312   /* HERE ("start"); */
313
314   entity *ent = get_irg_entity (graph);
315   type *mtp = get_entity_type (ent);
316   ir_node **args = find_irg_args (graph);
317   type *ctp = get_method_param_type (mtp, 1); /* ctp == char[]*[]* */
318   desc_t *arg_desc;
319   pto_t *arg_pto;
320
321   /* 'main' has signature 'void(int, char[]*[]*)' */
322   assert (NULL == args [2]);
323
324   assert (is_Pointer_type (ctp));
325
326   ctp = get_pointer_points_to_type (ctp); /* ctp == char[]*[] */
327
328   assert (is_Array_type (ctp));
329
330   arg_desc = new_name (ctp, args [1], -1);
331   arg_pto = new_pto (args [1]);
332   /* todo: simulate 'store' to arg1[] ?!? */
333   qset_insert (arg_pto->values, arg_desc);
334
335   set_node_pto (args [1], arg_pto);
336
337   DBGPRINT (1, (stdout, "%s:%i (%s[%li])\n",
338                 __FUNCTION__, __LINE__,
339                 OPNAME (args [1]), OPNUM (args [1])));
340
341 # ifdef TEST_MAIN_TYPE
342   ctp = get_array_element_type (ctp); /* ctp == char[]* */
343
344   assert (is_Pointer_type (ctp));
345
346   ctp = get_pointer_points_to_type (ctp); /* ctp == char[] */
347
348   assert (is_Array_type (ctp));
349
350   ctp = get_array_element_type (ctp); /* ctp == char */
351
352   assert (is_primitive_type (ctp));
353 # endif /* defined  TEST_MAIN_TYPE */
354
355   /* HERE ("end"); */
356 }
357
358 /* Initialise the Init module */
359 void pto_init_init (void)
360 {
361   pto_obst = (struct obstack*) xmalloc (sizeof (struct obstack));
362
363   obstack_init (pto_obst);
364 }
365
366 /* Cleanup the Init module */
367 void pto_init_cleanup (void)
368 {
369   obstack_free (pto_obst, NULL);
370   memset (pto_obst, 0x00, sizeof (struct obstack));
371   free (pto_obst);
372   pto_obst = NULL;
373 }
374
375
376 /* Initialise the Names of the Types/Entities */
377 void pto_init_type_names (void)
378 {
379   /* HERE ("start"); */
380   type_walk (clear_type_link, NULL, NULL);
381   /* HERE ("end"); */
382 }
383
384 /* Initialise the given graph for a new pass run */
385 void pto_init_graph (ir_graph *graph)
386 {
387   ir_node **proj_args;
388   graph_info_t *ginfo = ecg_get_info (graph);
389   const int n_ctxs = ginfo->n_ctxs;
390
391   /* only for debugging stuff: */
392   entity *ent = get_irg_entity (graph);
393   const char *ent_name = (char*) get_entity_name (ent);
394   const char *own_name = (char*) get_type_name (get_entity_owner (ent));
395
396   DBGPRINT (2, (stdout, "%s: init \"%s.%s\" for %i ctxs\n",
397                 __FUNCTION__,
398                 own_name, ent_name, n_ctxs));
399
400   /* HERE ("start"); */
401
402   clear_graph_links     (graph);
403   pto_init_graph_allocs (graph);
404
405   /* HERE ("end"); */
406
407   assert (NULL == get_irg_proj_args (graph));
408   proj_args = find_irg_args (graph);
409   set_irg_proj_args (graph, proj_args);
410   assert (proj_args == get_irg_proj_args (graph));
411 }
412
413 /* Reset the given graph for a new pass run */
414 void pto_reset_graph_pto (ir_graph *graph, int ctx_idx)
415 {
416   reset_env_t *reset_env;
417
418   reset_env = (reset_env_t*) xmalloc (sizeof (reset_env_t));
419   reset_env->ctx_idx = ctx_idx;
420
421   /* HERE ("start"); */
422
423   irg_walk_graph (graph, reset_node_pto, NULL, reset_env);
424
425   /* HERE ("end"); */
426   memset (reset_env, 0x00, sizeof (reset_env_t));
427   free (reset_env);
428 }
429
430 \f
431 /*
432   $Log$
433   Revision 1.19  2005/06/17 17:42:32  beck
434   added doxygen docu
435   fixed (void) function headers
436
437   Revision 1.18  2005/02/16 13:27:52  beck
438   added needed tv.h include
439
440   Revision 1.17  2005/01/14 14:12:51  liekweg
441   prepare gnu extension fix
442
443   Revision 1.16  2005/01/14 13:36:50  liekweg
444   don't put environments on the stack; handle consts
445
446   Revision 1.15  2005/01/10 17:26:34  liekweg
447   fixup printfs, don't put environments on the stack
448
449   Revision 1.14  2005/01/05 14:25:54  beck
450   renames all is_x*_type() functions to is_X*_type() to prevent name clash with EDG fronten
451
452   Revision 1.13  2004/12/21 15:07:55  beck
453   removed C99 contructs
454   removed unnecessary allocation
455   removed use of mode_P, use mode_is_reference() instead
456   removed handling of Const with pointer tarvals, these constructs are removed
457
458   Revision 1.12  2004/12/20 17:41:14  liekweg
459   __unused -> _unused
460
461   Revision 1.11  2004/12/20 17:34:35  liekweg
462   fix recursion handling
463
464   Revision 1.10  2004/12/15 13:31:00  liekweg
465   store ctx idx in names
466
467   Revision 1.9  2004/12/15 09:18:18  liekweg
468   pto_name.c
469
470   Revision 1.8  2004/12/02 16:17:51  beck
471   fixed config.h include
472
473   Revision 1.7  2004/11/30 14:47:54  liekweg
474   fix initialisation; do correct iteration
475
476   Revision 1.6  2004/11/26 16:00:41  liekweg
477   recognize class consts vs. ptr-to-class consts
478
479   Revision 1.5  2004/11/24 14:53:56  liekweg
480   Bugfixes
481
482   Revision 1.4  2004/11/20 21:21:56  liekweg
483   Finalise initialisation
484
485   Revision 1.3  2004/11/18 16:37:07  liekweg
486   rewrite
487
488
489 */