5 * File name: ir/ana2/pto_util.c
6 * Purpose: Pto Utilities
9 * Created: Mon 18 Oct 2004
11 * Copyright: (c) 1999-2004 Universität Karlsruhe
12 * Licence: This file is protected by GPL - GNU GENERAL PUBLIC LICENSE.
20 # include "pto_util.h"
32 int get_pto_verbose (void); /* grrr, can't include pto.h */
34 # define DBGPRINT(lvl, msg) if (get_pto_verbose () > lvl) { fprintf msg; }
36 static int pto_id = 0; /* only for pto_t->kind */
38 static obj_desc_t *obj_descrs = NULL; /* list of all descrs */
41 See whether the given entity is a field.
43 static int is_field (entity *ent)
45 type *tp = get_entity_type (ent);
47 if (is_primitive_type (tp) || is_pointer_type (tp)) {
55 Helper to collect_fields(type*): collect all fields of the given
56 clazz and its super classes into the given obstack.
58 # define obstack_chunk_alloc xmalloc
59 # define obstack_chunk_free free
61 static void _collect_fields (type *clazz, struct obstack *obst)
63 int n_members = get_class_n_members (clazz);
64 int n_supers = get_class_n_supertypes (clazz);
67 for (i = 0; i < n_members; i ++) {
68 entity *ent = get_class_member (clazz, i);
71 obstack_ptr_grow (obst, ent);
73 DBGPRINT (4, (stdout, "%s: add entity \"%s.%s\"\n",
75 get_type_name (clazz),
76 get_entity_name (ent)));
80 for (i = 0; i < n_supers; i ++) {
81 type *s_clazz = get_class_supertype (clazz, i);
83 _collect_fields (s_clazz, obst);
88 Collect the fields of the given class and its super classes into an array.
89 The last entry of the array is written NULL.
91 static entity **collect_fields (type *clazz)
93 if (NULL != get_type_link (clazz)) {
94 DBGPRINT (3, (stdout, "%s: reusing field list for \"%s\"\n",
95 __FUNCTION__, get_type_name (clazz)));
97 return ((entity **) get_type_link (clazz));
99 DBGPRINT (2, (stdout, "%s: new field list for \"%s\"\n",
100 __FUNCTION__, get_type_name (clazz)));
105 obstack_init (&obst);
107 _collect_fields (clazz, &obst);
109 /* append terminating NULL */
110 int *the_null = NULL;
111 obstack_ptr_grow (&obst, the_null);
113 int n_fields = obstack_object_size (&obst) / sizeof (void*);
115 entity ** fields = (entity**) xmalloc (n_fields * sizeof (entity*));
116 void *tmp = obstack_finish (&obst);
118 memcpy (fields, tmp, n_fields * sizeof (entity*));
120 obstack_free (&obst, NULL);
122 set_type_link (clazz, (void*) fields);
126 # undef obstack_chunk_alloc
127 # undef obstack_chunk_free
131 Environment for find_irg_args
133 typedef struct find_irg_args_env {
136 } find_irg_args_env_t;
139 Helper for find_irg_args
141 static void find_irg_arg (ir_node *node, void *env)
143 find_irg_args_env_t *arg_env = (find_irg_args_env_t*) env;
145 if (iro_Proj == get_irn_opcode (node)) {
146 if (arg_env->arg == get_Proj_pred (node)) {
147 long n = get_Proj_proj (node);
149 assert (! arg_env->args [n]);
151 arg_env->args [n] = node;
157 Print the given obj desc to stdout
159 static void obj_desc_print (obj_desc_t *obj)
161 if (obj_kind_obj == obj->kind) {
163 obj_obj_desc_t *obj_obj = (obj_obj_desc_t*) obj;
166 fprintf (stdout, "obj desc 0x%08x for type \"%s\"\n",
167 (int) obj, get_type_name (obj->tp));
169 for (i = 0; i < obj_obj->n_fields; i ++) {
170 fprintf (stdout, " \"%s\" -> ", get_entity_name (obj_obj->fields [i]));
171 qset_print (obj_obj->vals [i], stdout);
174 } else if (obj_kind_array == obj->kind) {
176 obj_arr_desc_t *obj_arr = (obj_arr_desc_t*) obj;
178 fprintf (stdout, "arr desc 0x%08x for type \"%s\"\n",
179 (int) obj, get_type_name (obj->tp));
181 fprintf (stdout, " [] -> ");
182 qset_print (obj_arr->val, stdout);
184 fprintf (stderr, "%s:%i: Invalid desc\n", __FILE__, __LINE__);
189 Get the entity of a ptr
191 entity *get_ptr_ent (ir_node *ptr)
194 const opcode ptr_op = get_irn_opcode (ptr);
197 ent = get_Sel_entity (ptr);
200 case (iro_SymConst): {
201 ent = get_SymConst_entity (ptr);
205 fprintf (stderr, "%s: no ent for ptr=%s[%ld]\n",
207 get_op_name (get_irn_op (ptr)),
208 get_irn_node_nr (ptr));
218 Ctors for the pto types
222 Create a new Object Description for the given type
224 obj_desc_t *obj_desc_new (type *tp)
227 obj_desc_t *res = NULL;
229 if (is_array_type (tp)) {
230 obj_arr_desc_t *arr_res = (obj_arr_desc_t*) xmalloc (sizeof (obj_arr_desc_t));
232 arr_res->val = qset_new (N_INITIAL_OBJS);
234 res = (obj_desc_t*) arr_res;
235 res->kind = obj_kind_array;
237 DBGPRINT (0, (stdout, "%s: new ARRAY desc 0x%08x for %s\n",
238 __FUNCTION__, (int) res, get_type_name (tp)));
239 } else if (is_class_type (tp)) {
240 obj_obj_desc_t *obj_res = (obj_obj_desc_t*) xmalloc (sizeof (obj_obj_desc_t));
244 DBGPRINT (0, (stdout, "%s: new CLAZZ desc 0x%08x for %s\n",
245 __FUNCTION__, (int) obj_res, get_type_name (tp)));
247 obj_res->fields = collect_fields (tp);
249 /* grr, must count */
250 for (tmp = obj_res->fields; NULL != *tmp; tmp ++) {
253 obj_res->n_fields = n_fields;
255 obj_res->vals = (qset_t **) xmalloc (n_fields * sizeof (qset_t*));
257 for (i = 0; i < n_fields; i ++) {
258 obj_res->vals [i] = qset_new (N_INITIAL_OBJS);
261 res = (obj_desc_t*) obj_res;
262 res->kind = obj_kind_obj;
264 assert (0 && "unknown type");
269 res->next = obj_descrs;
272 res->is_dummy = FALSE;
273 # endif /* defined PTO_DUMMY */
280 Mark an obj desc as a dummy
282 void obj_desc_set_dummy (obj_desc_t *obj_desc)
284 obj_desc->is_dummy = TRUE;
288 Say whether an obj desc is a dummy
290 int obj_desc_is_dummy (obj_desc_t *obj_desc)
292 return (obj_desc->is_dummy);
294 # endif /* defined PTO_DUMMY */
297 Deallocate an obj desc
299 void obj_desc_delete (obj_desc_t *obj_desc)
301 if (obj_kind_obj == obj_desc->kind) {
303 obj_obj_desc_t *obj_obj = (obj_obj_desc_t*) obj_desc;
306 memset (obj_obj->fields, 0x00, obj_obj->n_fields * sizeof (entity*));
307 free (obj_obj->fields);
309 for (i = 0; i < obj_obj->n_fields; i ++) {
310 qset_delete (obj_obj->vals [i]);
313 memset (obj_obj->vals, 0x00, obj_obj->n_fields * sizeof (entity*));
314 free (obj_obj->vals);
316 memset (obj_obj, 0x00, sizeof (obj_obj_desc_t));
321 obj_arr_desc_t *obj_arr = (obj_arr_desc_t*) obj_desc;
323 qset_delete (obj_arr->val);
325 memset (obj_arr, 0x00, sizeof (obj_arr_desc_t));
332 List all obj descs that have been created. If tp is given non-NULL,
333 only descs for this type are listed, else all types are listed.
335 void obj_desc_list_all (type *tp)
337 obj_desc_t *cur = obj_descrs;
339 while (NULL != cur) {
340 if ((NULL == tp) || (tp == cur->tp)) {
341 obj_desc_print (cur);
349 Create a new pto value containing no names.
351 pto_t *pto_new_empty (ir_node *node)
353 pto_t *pto = (pto_t*) xmalloc (sizeof (pto_t));
357 pto->objs = qset_new (N_INITIAL_OBJS);
363 Create a new pto value containing a name of the given type.
365 pto_t *pto_new_name (ir_node *node, type *tp)
367 pto_t *pto = pto_new_empty (node);
368 obj_desc_t *desc = obj_desc_new (tp);
370 qset_insert (pto->objs, desc);
378 void pto_delete (pto_t *pto)
380 qset_delete (pto->objs);
382 memset (pto, 0x00, sizeof (pto_t));
392 Sanity checking on a pto_t
394 void check_pto (pto_t *pto)
396 assert (&pto_id == pto->kind);
400 Add the given name to the given pto.
402 void pto_add_name (pto_t *pto, obj_desc_t *obj)
404 qset_insert (pto->objs, obj);
408 Add all the given names to the given pto.
410 void pto_add_all_names (pto_t *pto, qset_t *objs)
412 qset_insert_all (pto->objs, objs);
417 Find the arguments of a graph. For a method that has n args, the
418 result array has 'n+1' entries, the last of which is written NULL.
420 ir_node **find_irg_args (ir_graph *graph)
422 type *tp = get_entity_type (get_irg_entity (graph));
423 const int n_args = get_method_n_params (tp);
424 ir_node **args = (ir_node**) xmalloc (sizeof (ir_node*) * (n_args+1));
425 ir_node *arg = get_irg_args (graph);
426 find_irg_args_env_t *arg_env =
427 (find_irg_args_env_t*) xmalloc (sizeof (find_irg_args_env_t));
429 arg_env->args = args;
432 /* or use get_irg_end ?!? */
434 ir_graph *save = get_current_ir_graph ();
435 set_current_ir_graph (graph);
436 irg_walk (get_irg_end (graph), find_irg_arg, NULL, arg_env);
437 set_current_ir_graph (save);
442 args [n_args] = NULL;
448 Perform a lookup of the contents of the given field in the given pto
450 qset_t *pto_lookup (obj_desc_t *obj_desc, entity *ent)
454 if (obj_kind_obj == obj_desc->kind) {
456 obj_obj_desc_t *obj_obj = (obj_obj_desc_t*) obj_desc;
459 assert (NULL != ent);
461 for (i = 0; NULL != obj_obj->fields [i]; i ++) {
462 if (obj_obj->fields [i] == ent) {
467 assert (obj_obj->fields [i]); /* this *must* find a field */
469 res = obj_obj->vals [i];
472 obj_arr_desc_t *arr_obj = (obj_arr_desc_t*) obj_desc;
474 assert (NULL == ent);
483 Enter the given ptr values into the given field of the given pto
485 void pto_enter (obj_desc_t *obj_desc, entity *ent, pto_t *pto)
487 if (obj_kind_obj == obj_desc) {
489 obj_obj_desc_t *obj_obj = (obj_obj_desc_t*) obj_desc;
492 for (i = 0; NULL != obj_obj->fields [i]; i ++) {
493 if (obj_obj->fields [i] == ent) {
498 assert (obj_obj->fields [i]); /* this *must* find a field */
500 qset_insert_all (obj_obj->vals [i], pto->objs);
503 assert (0 && "array enter not yet implemented");
510 Revision 1.3 2004/11/04 14:58:38 liekweg
511 expanded pto, added initialisation, added debugging printing
513 Revision 1.2 2004/10/25 11:59:45 liekweg
516 Revision 1.1 2004/10/22 15:10:51 liekweg
517 moved utils to pto_util