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