5 File name: ir/ana/pto_name.c
6 Purpose: Names for abstract objects
9 Created: Sat Nov 13 19:35:27 CET 2004
11 Copyright: (c) 1999-2004 Universität Karlsruhe
12 Licence: This file is protected by the GPL - GNU GENERAL PUBLIC LICENSE.
20 pto_name: Names for abstract objects
24 # include "pto_name.h"
25 # include "pto_util.h"
27 # include <string.h> /* for memcpy */
35 # include "pto_debug.h"
38 # define obstack_chunk_alloc xmalloc
39 # define obstack_chunk_free free
41 # define NALLOC(size) obstack_alloc (name_obst, size)
43 /* Local Data Types: */
45 /* Local Variables: */
46 struct obstack *qset_obst = NULL;
47 struct obstack *name_obst = NULL;
49 static desc_t *all_descs = NULL;
51 static int name_id = 0;
56 static int last_col_idx = 0;
58 /* Local Prototypes: */
59 static int pto_name_alloc_color (desc_t*);
60 static void pto_name_set_color (desc_t*, int);
61 # endif /* defined PTO_COLOR */
63 /* ===================================================
65 =================================================== */
67 /* set a nice color to an object descriptor */
68 static void pto_name_set_obj_color (obj_desc_t *obj_desc, int col_idx)
72 for (i = 0; i < obj_desc->n_fields; i ++) {
73 qset_t *ptos = obj_desc->values [i];
75 desc_t *tgt = (desc_t*) qset_start (ptos);
78 pto_name_set_color (tgt, col_idx);
80 tgt = (desc_t*) qset_next (ptos);
85 /* set a nice color to an array descriptor */
86 static void pto_name_set_arr_color (arr_desc_t *arr_desc, int col_idx)
88 qset_t *ptos = arr_desc->value;
90 desc_t *tgt = (desc_t*) qset_start (ptos);
93 pto_name_set_color (tgt, col_idx);
95 tgt = (desc_t*) qset_next (ptos);
99 /* set a nice color to a descriptor */
100 static void pto_name_set_color (desc_t *desc, int col_idx)
102 /* assert (0 == desc->col_idx); */
104 desc->col_idx = col_idx;
106 if (FALSE == desc->visit) {
108 if (object == desc->kind) {
109 pto_name_set_obj_color ((obj_desc_t*) desc, col_idx);
110 } else if (array == desc->kind) {
111 pto_name_set_arr_color ((arr_desc_t*) desc, col_idx);
119 /* allocate nice colors for an object descriptor */
120 static int pto_name_alloc_obj_color (obj_desc_t *obj_desc)
125 for (i = 0; (0 == col_idx) && (i < obj_desc->n_fields); i ++) {
126 qset_t *ptos = obj_desc->values [i];
127 desc_t *tgt = (desc_t*) qset_start (ptos);
129 while ((0 == col_idx) && (NULL != tgt)) {
130 col_idx = pto_name_alloc_color (tgt);
132 tgt = (desc_t*) qset_next (ptos);
139 /* allocate nice colors for an array descriptor */
140 static int pto_name_alloc_arr_color (arr_desc_t *arr_desc)
144 qset_t *ptos = arr_desc->value;
146 desc_t *tgt = (desc_t*) qset_start (ptos);
148 while ((NULL != tgt) && (0 == col_idx)) {
149 col_idx = pto_name_alloc_color (tgt);
150 tgt = (desc_t*) qset_next (ptos);
156 /* allocate nice colors for the given descriptor */
157 static int pto_name_alloc_color (desc_t *desc)
159 if (0 != desc->col_idx) {
160 return (desc->col_idx);
165 if (FALSE == desc->visit) {
167 if (object == desc->kind) {
168 col_idx = pto_name_alloc_obj_color ((obj_desc_t*) desc);
169 } else if (array == desc->kind) {
170 col_idx = pto_name_alloc_arr_color ((arr_desc_t*) desc);
176 col_idx = ++ last_col_idx;
179 pto_name_set_color (desc, col_idx);
184 /* allocate nice colors */
185 static void pto_name_alloc_colors (void)
187 desc_t *desc = all_descs;
189 while (NULL != desc) {
190 pto_name_alloc_color (desc);
195 # endif /* defined PTO_COLOR */
197 /* See whether the given entity is a field. */
198 static int is_field (entity *ent)
200 type *tp = get_entity_type (ent);
202 if (is_primitive_type (tp) || is_pointer_type (tp)) {
203 /* actually, we don't get by by restricting ourselves to pointer types */
210 /* Helper to collect_fields(type*): collect all fields of the given
211 clazz and its super classes into the given obstack. */
212 static void _collect_fields (type *clazz, struct obstack *obst)
214 int n_members = get_class_n_members (clazz);
215 int n_supers = get_class_n_supertypes (clazz);
218 for (i = 0; i < n_members; i ++) {
219 entity *ent = get_class_member (clazz, i);
221 if (is_field (ent)) {
222 if (allocation_static != get_entity_allocation (ent)) {
223 obstack_ptr_grow (obst, ent);
228 for (i = 0; i < n_supers; i ++) {
229 type *s_clazz = get_class_supertype (clazz, i);
231 _collect_fields (s_clazz, obst);
235 /* Collect the fields of the given class and its super classes into an array.
236 The last entry of the array is written NULL. */
237 static entity **collect_fields (type *clazz)
239 if (NULL != get_type_link (clazz)) {
240 DBGPRINT (3, (stdout, "%s: reusing field list for \"%s\"\n",
241 __FUNCTION__, get_type_name (clazz)));
243 return ((entity **) get_type_link (clazz));
245 DBGPRINT (2, (stdout, "%s: new field list for \"%s\"\n",
246 __FUNCTION__, get_type_name (clazz)));
251 obstack_init (&obst);
253 _collect_fields (clazz, &obst);
255 /* append terminating NULL */
256 int *the_null = NULL;
257 obstack_ptr_grow (&obst, the_null);
259 int n_fields = obstack_object_size (&obst) / sizeof (void*);
261 entity ** fields = (entity**) NALLOC (n_fields * sizeof (entity*));
262 void *tmp = obstack_finish (&obst);
264 memcpy (fields, tmp, n_fields * sizeof (entity*));
266 obstack_free (&obst, NULL);
268 set_type_link (clazz, (void*) fields);
273 /* Write the intro text for a name dump into the given stream */
274 static void pto_name_dump_start (FILE *stream)
277 pto_name_alloc_colors ();
278 # endif /* defined PTO_COLOR */
280 fprintf (stream, "digraph \"Names\" {\n");
281 fprintf (stream, "\tgraph [rankdir=\"LR\", ordering=\"out\", size=\"11,7\", rotate=\"90\"];\n");
282 fprintf (stream, "\tnode [shape=\"record\", style=\"filled\"];\n");
283 fprintf (stream, "\tedge [color=\"black\"];\n");
284 fprintf (stream, "\n");
287 /* Write the extro text for a name dump into the given stream */
288 static void pto_name_dump_finish (FILE *stream)
290 fprintf (stream, "}\n");
293 /* Write a node for the given descriptor into the given stream */
294 static void pto_name_dump_desc (desc_t *desc, FILE *stream)
297 const char *tp_name = get_type_name (tp);
299 fprintf (stream, "\t/* %s \"%s\" */\n",
300 object == desc->kind ? "Object" : "Array",
303 fprintf (stream, "\tdesc_%i [label=\"<HEAD>type \\[%i\\]",
306 if (-1 != desc->ctx) {
307 fprintf (stream, ", ctx = %i", desc->ctx);
309 fprintf (stream, " (global)");
312 fprintf (stream, "\\lname=\\\"%s\\\"",
315 ir_node *nd = desc->node;
318 ir_graph *graph = get_irn_irg (nd);
319 entity *method = get_irg_entity (graph);
320 const char *ent_name = get_entity_name (method);
321 const char *own_name = get_type_name (get_entity_owner (method));
323 fprintf (stream, "\\lnode=%s\\[%li\\]",
324 get_op_name (get_irn_op (nd)),
325 get_irn_node_nr (nd));
326 fprintf (stream, "\\lgraph=\\\"%s.%s\\\"",
331 if (desc->kind == object) {
332 obj_desc_t *obj_desc = (obj_desc_t*) desc;
335 for (i = 0; i < obj_desc->n_fields; i ++) {
336 entity *field = obj_desc->fields [i];
338 if (is_pointer_type (get_entity_type (field))) {
339 const char *ent_name = get_entity_name (field);
341 fprintf (stream, "|<%i>%s", i, ent_name);
344 } else if (array == desc->kind) {
345 fprintf (stream, "|<arr>[]");
347 assert (0 && "invalid descriptor");
350 /* end label string */
351 fprintf (stream, "\"");
354 int col_idx = desc->col_idx;
355 float hue = (float) col_idx / (float) last_col_idx;
356 float sat = 1.000; /* 0.300 .. 1.000 */
357 float val = 0.800; /* 0.300 .. 1.000 */
359 # define MAX_COLORS 12
360 if (last_col_idx > MAX_COLORS) {
361 /* too many colors ... vary value too */
362 float div = (float) MAX_COLORS / (float) last_col_idx;
364 sat = (div * ((col_idx / MAX_COLORS)));
365 val = (div * ((col_idx / MAX_COLORS)));
367 col_idx = col_idx % MAX_COLORS;
368 hue = (float) col_idx / (float) MAX_COLORS;
370 // re-adjust sat and val
372 const float sat_min = 0.200; /* 0.200 .. 0.400 */
373 const float val_min = 0.300; /* 0.300 .. 0.400 */
375 sat = sat_min + ((1.0 - sat_min) * sat);
376 val = val_min + ((1.0 - val_min) * val);
381 fprintf (stream, ", color=\"%01.3f, %01.3f, %01.3f\"", hue, sat, val);
385 if ((hue > 0.3) && (sat < 0.5)) {
387 } else if (sat < 0.4) {
393 fprintf (stream, ", fontcolor=\"%s\"", fontcolor);
394 # else /* if defined PTO_COLOR */
395 fprintf (stream, ", color=\"lightgrey\"");
396 # endif /* defined PTO_COLOR */
399 fprintf (stream, "];\n");
400 fprintf (stream, "\n");
403 if (desc->kind == object) {
404 obj_desc_t *obj_desc = (obj_desc_t*) desc;
407 for (i = 0; i < obj_desc->n_fields; i ++) {
408 desc_t *tgt = (desc_t*) qset_start (obj_desc->values [i]);
410 while (NULL != tgt) {
411 fprintf (stream, "\tdesc_%i:%i -> desc_%i:HEAD;\n",
412 desc->id, i, tgt->id);
414 tgt = (desc_t*) qset_next (obj_desc->values [i]);
417 } else if (array == desc->kind) {
418 arr_desc_t *arr_desc = (arr_desc_t*) desc;
420 desc_t *tgt = (desc_t*) qset_start (arr_desc->value);
422 while (NULL != tgt) {
423 fprintf (stream, "\tdesc_%i:arr -> desc_%i:HEAD;\n",
426 tgt = (desc_t*) qset_next (arr_desc->value);
430 fprintf (stream, "\n");
434 /* ===================================================
435 Exported Implementation:
436 =================================================== */
437 /* Find the given descriptor's entry for the given entity */
438 qset_t *get_entry (desc_t *desc, entity *ent)
441 if (desc->kind == object) {
442 obj_desc_t *obj_desc = (obj_desc_t*) desc;
444 const int n_fields = obj_desc->n_fields;
446 for (i = 0; i < n_fields; i ++) {
447 if (ent == obj_desc->fields [i]) {
448 return (obj_desc->values [i]);
452 assert (0 && "entry not found");
453 } else if (desc->kind == array) {
454 arr_desc_t *arr_desc = (arr_desc_t*) desc;
456 return (arr_desc->value);
458 assert (0 && "invalid descriptor");
463 /* get a new descriptor for the given type at the given node */
464 desc_t *new_name (type *tp, ir_node *node, int ctx)
468 assert ((is_class_type (tp) || is_array_type (tp)) && "unsuitable type");
470 DBGPRINT (2, (stdout, "%s: new name for type \"%s\"\n", __FUNCTION__,
471 get_type_name (tp)));
474 if (is_class_type (tp)) {
475 obj_desc_t *obj_desc = (obj_desc_t*) NALLOC (sizeof (obj_desc_t));
479 obj_desc->kind = object;
480 obj_desc->fields = collect_fields (tp);
482 for (n_fields = 0; (NULL != obj_desc->fields [n_fields]); n_fields ++) {
483 /* nothing, just count ... */
486 obj_desc->n_fields = n_fields;
487 obj_desc->values = (qset_t**) NALLOC (n_fields * sizeof (qset_t));
489 for (i = 0; i < n_fields; i ++) {
490 obj_desc->values [i] = qset_new (N_INITIAL_OJBS, qset_obst);
493 desc = (desc_t*) obj_desc;
494 } else if (is_array_type (tp)) {
495 arr_desc_t *arr_desc = (arr_desc_t*) NALLOC (sizeof (arr_desc_t));
497 arr_desc->kind = array;
498 arr_desc->value = qset_new (N_INITIAL_OJBS, qset_obst);
500 desc = (desc_t*) arr_desc;
503 desc->id = name_id ++;
510 desc->prev = all_descs;
516 # define N_GLOB_INITIAL_FIELDS 20
517 static obj_desc_t *obj_glob = NULL;
518 static int n_glob_fields = N_GLOB_INITIAL_FIELDS;
520 /* get a new descriptor for the given (presumably static) entity */
521 desc_t *new_ent_name (entity *ent)
525 type *tp = get_entity_type (ent);
527 assert (is_pointer_type (tp));
528 tp = get_pointer_points_to_type (tp);
529 assert (is_class_type (tp));
531 DBGPRINT (2, (stdout, "%s: new name for entity \"%s\"\n", __FUNCTION__,
532 get_entity_name (ent)));
533 DBGEXE (2, (fflush (stdout)));
535 assert (((allocation_static == get_entity_allocation (ent)) ||
536 (allocation_automatic == get_entity_allocation (ent))) &&
537 "not a static/automatic field");
539 if (NULL == obj_glob) {
540 obj_glob = (obj_desc_t*) NALLOC (sizeof (obj_desc_t));
542 obj_glob->id = name_id ++;
544 obj_glob->col_idx = 0;
545 obj_glob->visit = FALSE;
546 obj_glob->kind = object;
547 obj_glob->tp = get_glob_type ();
548 obj_glob->node = NULL;
550 obj_glob->n_fields = 0;
551 obj_glob->fields = (entity**) NALLOC (N_GLOB_INITIAL_FIELDS * sizeof (entity*));
552 obj_glob->values = (qset_t**) NALLOC (N_GLOB_INITIAL_FIELDS * sizeof (qset_t*));
554 obj_glob->prev = all_descs;
555 all_descs = (desc_t*) obj_glob;
558 for (i = 0; missing && (i < obj_glob->n_fields); i ++) {
559 if (ent == obj_glob->fields [i]) {
565 if (obj_glob->n_fields == n_glob_fields) {
566 entity **fields = obj_glob->fields;
567 qset_t **values = obj_glob->values;
570 obj_glob->fields = (entity**) NALLOC (n_glob_fields * sizeof (entity*));
571 obj_glob->values = (qset_t**) NALLOC (n_glob_fields * sizeof (qset_t*));
573 memcpy (obj_glob->fields, fields, obj_glob->n_fields * sizeof (entity*));
574 memcpy (obj_glob->values, values, obj_glob->n_fields * sizeof (qset_t*));
580 obj_glob->fields [obj_glob->n_fields ] = ent;
581 obj_glob->values [obj_glob->n_fields ++] = qset_new (N_INITIAL_OJBS, qset_obst);
584 return ((desc_t*) obj_glob);
586 # undef N_GLOB_INITIAL_FIELDS
588 /* Dump all names to a file of the given name */
589 void pto_dump_names (const char *name)
591 desc_t *desc = all_descs;
592 FILE *stream = fopen (name, "w");
595 if (NULL == stream) {
596 fprintf (stderr, "%s: unable to open %s (%s)\n",
597 __FUNCTION__, name, strerror (errno));
601 pto_name_dump_start (stream);
603 while (NULL != desc) {
604 pto_name_dump_desc (desc, stream);
609 pto_name_dump_finish (stream);
613 /* Initialise the name module */
614 void pto_name_init ()
616 DBGPRINT (3, (stdout, "(%s:%i) %s\n", __FILE__, __LINE__, __FUNCTION__));
617 assert (NULL == name_obst);
618 assert (NULL == qset_obst);
620 name_obst = xmalloc (sizeof (struct obstack));
621 qset_obst = xmalloc (sizeof (struct obstack));
623 obstack_init (name_obst);
624 obstack_init (qset_obst);
627 /* Cleanup the name module */
628 void pto_name_cleanup ()
630 DBGPRINT (3, (stdout, "(%s:%i) %s\n", __FILE__, __LINE__, __FUNCTION__));
631 obstack_free (name_obst, NULL);
632 obstack_free (qset_obst, NULL);
634 memset (name_obst, 0x00, sizeof (struct obstack));
635 memset (qset_obst, 0x00, sizeof (struct obstack));
647 Revision 1.8 2004/12/15 13:30:30 liekweg
648 use DBGEXE correctly; print yet nicer names
650 Revision 1.7 2004/12/15 09:18:18 liekweg
653 Revision 1.6 2004/12/06 12:52:09 liekweg
656 Revision 1.4 2004/11/30 15:49:27 liekweg
659 Revision 1.3 2004/11/30 14:47:54 liekweg
660 fix initialisation; do correct iteration
662 Revision 1.2 2004/11/24 14:53:56 liekweg
665 Revision 1.1 2004/11/18 16:37:34 liekweg