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