4 * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
6 * This file is part of libFirm.
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.
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.
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
24 * @brief Initialisation Functions
26 * @date Sat Nov 13 19:35:27 CET 2004
34 pto_init: Initialisation Functions
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"
53 # include "typewalk.h"
61 # define obstack_chunk_alloc xmalloc
62 # define obstack_chunk_free free
64 /* Local Data Types: */
65 typedef struct init_env_str
70 typedef struct reset_env_str
75 /* Local Variables: */
76 extern struct obstack *qset_obst; /* from pto_name */
78 static struct obstack *pto_obst = NULL; /* all pto_t's go onto this one */
80 /* Local Prototypes: */
82 /* ===================================================
84 =================================================== */
85 /** Allocate a new pto */
86 static pto_t *new_pto (ir_node *node)
88 pto_t *pto = obstack_alloc (pto_obst, sizeof (pto_t));
89 pto->values = qset_new (N_INITIAL_OJBS, qset_obst);
94 /** Allocate a new alloc_pto */
95 static alloc_pto_t *new_alloc_pto (ir_node *alloc, int n_ctxs)
98 alloc_pto_t *alloc_pto = obstack_alloc (pto_obst, sizeof (alloc_pto_t));
101 assert (op_Alloc == get_irn_op(alloc));
103 tp = get_Alloc_type (alloc);
105 alloc_pto->ptos = (pto_t**) obstack_alloc (pto_obst, n_ctxs * sizeof (pto_t*));
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);
116 /** Allocate a new pto for a symconst */
117 static pto_t* new_symconst_pto (ir_node *symconst)
123 assert (op_SymConst == get_irn_op(symconst));
125 pto = new_pto (symconst);
126 ent = get_SymConst_entity (symconst);
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);
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);
142 fprintf (stderr, "%s: not handled: %s[%li] (\"%s\")\n",
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");
150 qset_insert (pto->values, desc);
152 /* HERE3 ("end", own_name, ent_name); */
157 /* Helper to pto_init --- clear the link fields of class types */
158 static void clear_type_link (type_or_ent *thing, void *_unused)
160 if (is_type (thing)) {
161 ir_type *tp = (ir_type*) thing;
163 if (is_Class_type (tp)) {
164 DBGPRINT (1, (stdout, "%s (\"%s\")\n",
166 get_type_name (tp)));
168 set_type_link (tp, NULL);
170 } else if (is_entity (thing)) {
171 ir_entity *ent = (ir_entity*) thing;
173 DBGPRINT (1, (stdout, "%s (\"%s\")\n",
175 get_entity_name (ent)));
177 set_entity_link (ent, NULL);
181 /** Helper to pto_init_graph --- clear the links of the given node */
182 static void clear_node_link (ir_node *node, void *_unused)
184 set_irn_link (node, NULL);
187 /** Helper to pto_init_graph --- clear the links of all nodes */
188 static void clear_graph_links (ir_graph *graph)
190 irg_walk_graph (graph, clear_node_link, NULL, NULL);
193 /** Reset ALL the pto values for a new pass */
194 static void reset_node_pto (ir_node *node, void *env)
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);
200 /* HERE ("start"); */
205 case (iro_Block): /* END BLOCK only */
207 /* allocate 'empty' pto values */
208 pto_t *pto = new_pto (node);
209 set_node_pto (node, pto);
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];
217 DBGPRINT (1, (stdout, "%s: setting pto of \"%s[%li]\" for ctx %i\n",
223 assert (alloc_pto->curr_pto);
226 case (iro_SymConst): {
227 /* nothing, leave as-is */
231 /* basically, nothing */
232 DBGPRINT (2, (stdout, "%s: resetting pto of \"%s[%li]\"\n",
236 set_node_pto (node, NULL);
243 /** Initialise primary name sources */
244 static void init_pto (ir_node *node, void *env)
246 init_env_t *init_env = (init_env_t*) env;
247 int n_ctxs = init_env->n_ctxs;
249 ir_opcode op = get_irn_opcode (node);
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);
261 DBGPRINT (1, (stdout, "%s: new name \"%s\" for \"%s[%li]\"\n",
263 get_entity_name (ent),
271 alloc_pto_t *alloc_pto = new_alloc_pto (node, n_ctxs);
274 set_alloc_pto (node, alloc_pto);
276 tp = get_Alloc_type (node); /* debugging only */
277 DBGPRINT (1, (stdout, "%s: %i names \"%s\" for \"%s[%li]\"\n",
286 tarval *tv = get_Const_tarval (node);
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);
299 /* nothing --- handled by reset_node_pto on each pass */
308 /** Initialise the given graph for a new pass run */
309 static void pto_init_graph_allocs (ir_graph *graph)
311 graph_info_t *ginfo = ecg_get_info (graph);
312 init_env_t *init_env;
314 init_env = xmalloc (sizeof (init_env_t));
315 init_env->n_ctxs = ginfo->n_ctxs;
317 /* HERE ("start"); */
319 irg_walk_graph (graph, init_pto, NULL, init_env);
322 memset (init_env, 0x00, sizeof (init_env_t));
326 /* ===================================================
327 Exported Implementation:
328 =================================================== */
329 /* "Fake" the arguments to the main method */
330 void fake_main_args (ir_graph *graph)
332 /* HERE ("start"); */
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[]*[]* */
341 /* 'main' has signature 'void(int, char[]*[]*)' */
342 assert (NULL == args [2]);
344 assert (is_Pointer_type (ctp));
346 ctp = get_pointer_points_to_type (ctp); /* ctp == char[]*[] */
348 assert (is_Array_type (ctp));
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);
355 set_node_pto (args [1], arg_pto);
357 DBGPRINT (1, (stdout, "%s:%i (%s[%li])\n",
358 __FUNCTION__, __LINE__,
359 OPNAME (args [1]), OPNUM (args [1])));
361 # ifdef TEST_MAIN_TYPE
362 ctp = get_array_element_type (ctp); /* ctp == char[]* */
364 assert (is_Pointer_type (ctp));
366 ctp = get_pointer_points_to_type (ctp); /* ctp == char[] */
368 assert (is_Array_type (ctp));
370 ctp = get_array_element_type (ctp); /* ctp == char */
372 assert (is_primitive_type (ctp));
373 # endif /* defined TEST_MAIN_TYPE */
378 /* Initialise the Init module */
379 void pto_init_init (void)
381 pto_obst = (struct obstack*) xmalloc (sizeof (struct obstack));
383 obstack_init (pto_obst);
386 /* Cleanup the Init module */
387 void pto_init_cleanup (void)
389 obstack_free (pto_obst, NULL);
390 memset (pto_obst, 0x00, sizeof (struct obstack));
396 /* Initialise the Names of the Types/Entities */
397 void pto_init_type_names (void)
399 /* HERE ("start"); */
400 type_walk (clear_type_link, NULL, NULL);
404 /* Initialise the given graph for a new pass run */
405 void pto_init_graph (ir_graph *graph)
408 graph_info_t *ginfo = ecg_get_info (graph);
409 const int n_ctxs = ginfo->n_ctxs;
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));
416 DBGPRINT (2, (stdout, "%s: init \"%s.%s\" for %i ctxs\n",
418 own_name, ent_name, n_ctxs));
420 /* HERE ("start"); */
422 clear_graph_links (graph);
423 pto_init_graph_allocs (graph);
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));
433 /* Reset the given graph for a new pass run */
434 void pto_reset_graph_pto (ir_graph *graph, int ctx_idx)
436 reset_env_t *reset_env;
438 reset_env = (reset_env_t*) xmalloc (sizeof (reset_env_t));
439 reset_env->ctx_idx = ctx_idx;
441 /* HERE ("start"); */
443 irg_walk_graph (graph, reset_node_pto, NULL, reset_env);
446 memset (reset_env, 0x00, sizeof (reset_env_t));
453 Revision 1.23 2007/01/16 15:45:42 beck
454 renamed type opcode to ir_opcode
456 Revision 1.22 2006/12/13 19:46:47 beck
457 rename type entity into ir_entity
459 Revision 1.21 2006/06/08 10:49:07 beck
460 renamed type to ir_type
462 Revision 1.20 2005/12/05 12:19:54 beck
463 added missing include <assert.h> (not anymore included in libFirm)
465 Revision 1.19 2005/06/17 17:42:32 beck
467 fixed (void) function headers
469 Revision 1.18 2005/02/16 13:27:52 beck
470 added needed tv.h include
472 Revision 1.17 2005/01/14 14:12:51 liekweg
473 prepare gnu extension fix
475 Revision 1.16 2005/01/14 13:36:50 liekweg
476 don't put environments on the stack; handle consts
478 Revision 1.15 2005/01/10 17:26:34 liekweg
479 fixup printfs, don't put environments on the stack
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
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
490 Revision 1.12 2004/12/20 17:41:14 liekweg
493 Revision 1.11 2004/12/20 17:34:35 liekweg
494 fix recursion handling
496 Revision 1.10 2004/12/15 13:31:00 liekweg
497 store ctx idx in names
499 Revision 1.9 2004/12/15 09:18:18 liekweg
502 Revision 1.8 2004/12/02 16:17:51 beck
503 fixed config.h include
505 Revision 1.7 2004/11/30 14:47:54 liekweg
506 fix initialisation; do correct iteration
508 Revision 1.6 2004/11/26 16:00:41 liekweg
509 recognize class consts vs. ptr-to-class consts
511 Revision 1.5 2004/11/24 14:53:56 liekweg
514 Revision 1.4 2004/11/20 21:21:56 liekweg
515 Finalise initialisation
517 Revision 1.3 2004/11/18 16:37:07 liekweg