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"
30 # include <string.h> /* for memcpy */
39 # include "pto_debug.h"
43 # define obstack_chunk_alloc xmalloc
44 # define obstack_chunk_free free
46 # define NALLOC(size) obstack_alloc (name_obst, size)
48 /* Local Data Types: */
50 /* Local Variables: */
51 struct obstack *qset_obst = NULL;
52 struct obstack *name_obst = NULL;
54 static desc_t *all_descs = NULL;
56 static int name_id = 0;
61 static int last_col_idx = 0;
63 /* Local Prototypes: */
64 static int pto_name_alloc_color (desc_t*);
65 static void pto_name_set_color (desc_t*, int);
66 # endif /* defined PTO_COLOR */
68 /* ===================================================
70 =================================================== */
72 /* set a nice color to an object descriptor */
73 static void pto_name_set_obj_color (obj_desc_t *obj_desc, int col_idx)
77 for (i = 0; i < obj_desc->n_fields; i ++) {
78 qset_t *ptos = obj_desc->values [i];
80 desc_t *tgt = (desc_t*) qset_start (ptos);
83 pto_name_set_color (tgt, col_idx);
85 tgt = (desc_t*) qset_next (ptos);
90 /* set a nice color to an array descriptor */
91 static void pto_name_set_arr_color (arr_desc_t *arr_desc, int col_idx)
93 qset_t *ptos = arr_desc->value;
95 desc_t *tgt = (desc_t*) qset_start (ptos);
98 pto_name_set_color (tgt, col_idx);
100 tgt = (desc_t*) qset_next (ptos);
104 /* set a nice color to a descriptor */
105 static void pto_name_set_color (desc_t *desc, int col_idx)
107 /* assert (0 == desc->col_idx); */
109 desc->col_idx = col_idx;
111 if (FALSE == desc->visit) {
113 if (object == desc->kind) {
114 pto_name_set_obj_color ((obj_desc_t*) desc, col_idx);
115 } else if (array == desc->kind) {
116 pto_name_set_arr_color ((arr_desc_t*) desc, col_idx);
124 /* allocate nice colors for an object descriptor */
125 static int pto_name_alloc_obj_color (obj_desc_t *obj_desc)
130 for (i = 0; (0 == col_idx) && (i < obj_desc->n_fields); i ++) {
131 qset_t *ptos = obj_desc->values [i];
132 desc_t *tgt = (desc_t*) qset_start (ptos);
134 while ((0 == col_idx) && (NULL != tgt)) {
135 col_idx = pto_name_alloc_color (tgt);
137 tgt = (desc_t*) qset_next (ptos);
144 /* allocate nice colors for an array descriptor */
145 static int pto_name_alloc_arr_color (arr_desc_t *arr_desc)
149 qset_t *ptos = arr_desc->value;
151 desc_t *tgt = (desc_t*) qset_start (ptos);
153 while ((NULL != tgt) && (0 == col_idx)) {
154 col_idx = pto_name_alloc_color (tgt);
155 tgt = (desc_t*) qset_next (ptos);
161 /* allocate nice colors for the given descriptor */
162 static int pto_name_alloc_color (desc_t *desc)
166 if (0 != desc->col_idx) {
167 return (desc->col_idx);
170 if (FALSE == desc->visit) {
172 if (object == desc->kind) {
173 col_idx = pto_name_alloc_obj_color ((obj_desc_t*) desc);
174 } else if (array == desc->kind) {
175 col_idx = pto_name_alloc_arr_color ((arr_desc_t*) desc);
181 col_idx = ++ last_col_idx;
184 pto_name_set_color (desc, col_idx);
189 /* allocate nice colors */
190 static void pto_name_alloc_colors (void)
192 desc_t *desc = all_descs;
194 while (NULL != desc) {
195 pto_name_alloc_color (desc);
200 # endif /* defined PTO_COLOR */
202 /* See whether the given entity is a field. */
203 static int is_field (ir_entity *ent)
205 ir_type *tp = get_entity_type (ent);
207 if (is_Primitive_type (tp) || is_Pointer_type (tp)) {
208 /* actually, we don't get by by restricting ourselves to pointer types */
215 /* Helper to collect_fields(ir_type*): collect all fields of the given
216 clazz and its super classes into the given obstack. */
217 static void _collect_fields (ir_type *clazz, struct obstack *obst)
219 int n_members = get_class_n_members (clazz);
220 int n_supers = get_class_n_supertypes (clazz);
223 for (i = 0; i < n_members; i ++) {
224 ir_entity *ent = get_class_member (clazz, i);
226 if (is_field (ent)) {
227 if (allocation_static != get_entity_allocation (ent)) {
228 obstack_ptr_grow (obst, ent);
233 for (i = 0; i < n_supers; i ++) {
234 ir_type *s_clazz = get_class_supertype (clazz, i);
236 _collect_fields (s_clazz, obst);
240 /* Collect the fields of the given class and its super classes into an array.
241 The last entry of the array is written NULL. */
242 static ir_entity **collect_fields (ir_type *clazz)
249 if (NULL != get_type_link (clazz)) {
250 DBGPRINT (3, (stdout, "%s: reusing field list for \"%s\"\n",
252 get_type_name (clazz)));
254 return ((ir_entity **) get_type_link (clazz));
256 DBGPRINT (2, (stdout, "%s: new field list for \"%s\"\n",
258 get_type_name (clazz)));
261 obstack_init (&obst);
263 _collect_fields (clazz, &obst);
265 /* append terminating NULL */
266 obstack_ptr_grow (&obst, NULL);
268 n_fields = obstack_object_size (&obst) / sizeof (void*);
270 fields = NALLOC (n_fields * sizeof (ir_entity*));
271 tmp = obstack_finish(&obst);
273 memcpy (fields, tmp, n_fields * sizeof (ir_entity*));
275 obstack_free (&obst, NULL);
277 set_type_link (clazz, fields);
282 /* Write the intro text for a name dump into the given stream */
283 static void pto_name_dump_start (FILE *stream)
286 pto_name_alloc_colors ();
287 # endif /* defined PTO_COLOR */
289 fprintf (stream, "digraph \"Names\" {\n");
290 fprintf (stream, "\tgraph [rankdir=\"LR\", ordering=\"out\", size=\"11,7\", rotate=\"90\"];\n");
291 fprintf (stream, "\tnode [shape=\"record\", style=\"filled\"];\n");
292 fprintf (stream, "\tedge [color=\"black\"];\n");
293 fprintf (stream, "\n");
296 /* Write the extro text for a name dump into the given stream */
297 static void pto_name_dump_finish (FILE *stream)
299 fprintf (stream, "}\n");
302 /* Write a node for the given descriptor into the given stream */
303 static void pto_name_dump_desc (desc_t *desc, FILE *stream)
305 ir_type *tp = desc->tp;
306 const char *tp_name = get_type_name (tp);
309 fprintf (stream, "\t/* %s \"%s\" */\n",
310 object == desc->kind ? "Object" : "Array",
313 fprintf (stream, "\tdesc_%i [label=\"<HEAD>type \\[%i\\]",
316 if (-1 != desc->ctx) {
317 fprintf (stream, ", ctx = %i", desc->ctx);
319 fprintf (stream, " (global)");
322 fprintf (stream, "\\lname=\\\"%s\\\"",
328 ir_graph *graph = get_irn_irg (nd);
329 ir_entity *method = get_irg_entity (graph);
330 const char *ent_name = get_entity_name (method);
331 const char *own_name = get_type_name (get_entity_owner (method));
333 fprintf (stream, "\\lnode=%s\\[%li\\]",
334 get_op_name (get_irn_op (nd)),
335 get_irn_node_nr (nd));
336 fprintf (stream, "\\lgraph=\\\"%s.%s\\\"",
341 if (desc->kind == object) {
342 obj_desc_t *obj_desc = (obj_desc_t*) desc;
345 for (i = 0; i < obj_desc->n_fields; i ++) {
346 ir_entity *field = obj_desc->fields [i];
348 if (is_Pointer_type (get_entity_type (field))) {
349 const char *ent_name = get_entity_name (field);
351 fprintf (stream, "|<%i>%s", i, ent_name);
354 } else if (array == desc->kind) {
355 fprintf (stream, "|<arr>[]");
357 assert (0 && "invalid descriptor");
360 /* end label string */
361 fprintf (stream, "\"");
365 const char *fontcolor;
366 int col_idx = desc->col_idx;
367 float hue = (float) col_idx / (float) last_col_idx;
368 float sat = 1.000f; /* 0.300 .. 1.000 */
369 float val = 0.800f; /* 0.300 .. 1.000 */
371 # define MAX_COLORS 12
372 if (last_col_idx > MAX_COLORS) {
373 /* too many colors ... vary value too */
374 float div = (float) MAX_COLORS / (float) last_col_idx;
376 sat = (div * ((col_idx / MAX_COLORS)));
377 val = (div * ((col_idx / MAX_COLORS)));
379 col_idx = col_idx % MAX_COLORS;
380 hue = (float) col_idx / (float) MAX_COLORS;
382 // re-adjust sat and val
384 const float sat_min = 0.200f; /* 0.200 .. 0.400 */
385 const float val_min = 0.300f; /* 0.300 .. 0.400 */
387 sat = sat_min + ((1.0f - sat_min) * sat);
388 val = val_min + ((1.0f - val_min) * val);
393 fprintf (stream, ", color=\"%01.3f, %01.3f, %01.3f\"", hue, sat, val);
395 if ((hue > 0.3) && (sat < 0.5)) {
397 } else if (sat < 0.4) {
403 fprintf (stream, ", fontcolor=\"%s\"", fontcolor);
405 # else /* if defined PTO_COLOR */
406 fprintf (stream, ", color=\"lightgrey\"");
407 # endif /* defined PTO_COLOR */
410 fprintf (stream, "];\n");
411 fprintf (stream, "\n");
414 if (desc->kind == object) {
415 obj_desc_t *obj_desc = (obj_desc_t*) desc;
418 for (i = 0; i < obj_desc->n_fields; i ++) {
419 desc_t *tgt = (desc_t*) qset_start (obj_desc->values [i]);
421 while (NULL != tgt) {
422 fprintf (stream, "\tdesc_%i:%i -> desc_%i:HEAD;\n",
423 desc->id, i, tgt->id);
425 tgt = (desc_t*) qset_next (obj_desc->values [i]);
428 } else if (array == desc->kind) {
429 arr_desc_t *arr_desc = (arr_desc_t*) desc;
431 desc_t *tgt = (desc_t*) qset_start (arr_desc->value);
433 while (NULL != tgt) {
434 fprintf (stream, "\tdesc_%i:arr -> desc_%i:HEAD;\n",
437 tgt = (desc_t*) qset_next (arr_desc->value);
441 fprintf (stream, "\n");
445 /* ===================================================
446 Exported Implementation:
447 =================================================== */
448 /* Find the given descriptor's entry for the given entity */
449 qset_t *get_entry (desc_t *desc, ir_entity *ent)
452 if (desc->kind == object) {
453 obj_desc_t *obj_desc = (obj_desc_t*) desc;
455 const int n_fields = obj_desc->n_fields;
457 for (i = 0; i < n_fields; i ++) {
458 if (ent == obj_desc->fields [i]) {
459 return (obj_desc->values [i]);
463 assert (0 && "entry not found");
464 } else if (desc->kind == array) {
465 arr_desc_t *arr_desc = (arr_desc_t*) desc;
467 return (arr_desc->value);
469 assert (0 && "invalid descriptor");
475 /* get a new descriptor for the given type at the given node */
476 desc_t *new_name (ir_type *tp, ir_node *node, int ctx)
480 assert ((is_Class_type (tp) || is_Array_type (tp)) && "unsuitable type");
482 DBGPRINT (2, (stdout, "%s: new name for type \"%s\"\n",
484 get_type_name (tp)));
487 if (is_Class_type (tp)) {
488 obj_desc_t *obj_desc = NALLOC (sizeof (obj_desc_t));
492 obj_desc->kind = object;
493 obj_desc->fields = collect_fields (tp);
495 for (n_fields = 0; (NULL != obj_desc->fields [n_fields]); n_fields ++) {
496 /* nothing, just count ... */
499 obj_desc->n_fields = n_fields;
500 obj_desc->values = (qset_t**) NALLOC (n_fields * sizeof (qset_t*));
502 for (i = 0; i < n_fields; i ++) {
503 obj_desc->values [i] = qset_new (N_INITIAL_OJBS, qset_obst);
506 desc = (desc_t*) obj_desc;
507 } else if (is_Array_type (tp)) {
508 arr_desc_t *arr_desc = (arr_desc_t*) NALLOC (sizeof (arr_desc_t));
510 arr_desc->kind = array;
511 arr_desc->value = qset_new (N_INITIAL_OJBS, qset_obst);
513 desc = (desc_t*) arr_desc;
516 desc->id = name_id ++;
523 desc->prev = all_descs;
529 # define N_GLOB_INITIAL_FIELDS 20
530 static obj_desc_t *obj_glob = NULL;
531 static int n_glob_fields = N_GLOB_INITIAL_FIELDS;
533 /* get a new descriptor for the given (presumably static) entity */
534 desc_t *new_ent_name (ir_entity *ent)
538 ir_type *tp = get_entity_type (ent);
540 assert (is_Pointer_type (tp));
541 tp = get_pointer_points_to_type (tp);
542 assert (is_Class_type (tp));
544 DBGPRINT (2, (stdout, "%s: new name for entity \"%s\"\n",
546 get_entity_name (ent)));
547 DBGEXE (2, (fflush (stdout)));
549 assert (((allocation_static == get_entity_allocation (ent)) ||
550 (allocation_automatic == get_entity_allocation (ent))) &&
551 "not a static/automatic field");
553 if (NULL == obj_glob) {
554 obj_glob = (obj_desc_t*) NALLOC (sizeof (obj_desc_t));
556 obj_glob->id = name_id ++;
558 obj_glob->col_idx = 0;
559 obj_glob->visit = FALSE;
560 obj_glob->kind = object;
561 obj_glob->tp = get_glob_type ();
562 obj_glob->node = NULL;
564 obj_glob->n_fields = 0;
565 obj_glob->fields = (ir_entity**) NALLOC (N_GLOB_INITIAL_FIELDS * sizeof (ir_entity*));
566 obj_glob->values = (qset_t**) NALLOC (N_GLOB_INITIAL_FIELDS * sizeof (qset_t*));
568 obj_glob->prev = all_descs;
569 all_descs = (desc_t*) obj_glob;
572 for (i = 0; missing && (i < obj_glob->n_fields); i ++) {
573 if (ent == obj_glob->fields [i]) {
579 if (obj_glob->n_fields == n_glob_fields) {
580 ir_entity **fields = obj_glob->fields;
581 qset_t **values = obj_glob->values;
584 obj_glob->fields = (ir_entity**) NALLOC (n_glob_fields * sizeof (ir_entity*));
585 obj_glob->values = (qset_t**) NALLOC (n_glob_fields * sizeof (qset_t*));
587 memcpy (obj_glob->fields, fields, obj_glob->n_fields * sizeof (ir_entity*));
588 memcpy (obj_glob->values, values, obj_glob->n_fields * sizeof (qset_t*));
594 obj_glob->fields [obj_glob->n_fields ] = ent;
595 obj_glob->values [obj_glob->n_fields ++] = qset_new (N_INITIAL_OJBS, qset_obst);
598 return ((desc_t*) obj_glob);
600 # undef N_GLOB_INITIAL_FIELDS
602 /* Dump all names to a file of the given name */
603 void pto_dump_names (const char *name)
605 desc_t *desc = all_descs;
606 FILE *stream = fopen (name, "w");
609 if (NULL == stream) {
610 fprintf (stderr, "%s: unable to open %s (%s)\n",
611 __FUNCTION__, name, strerror (errno));
615 pto_name_dump_start (stream);
617 while (NULL != desc) {
618 pto_name_dump_desc (desc, stream);
623 pto_name_dump_finish (stream);
627 /* Initialise the name module */
628 void pto_name_init (void)
630 DBGPRINT (3, (stdout, "%s\n", __FUNCTION__));
631 assert (NULL == name_obst);
632 assert (NULL == qset_obst);
634 name_obst = xmalloc (sizeof (struct obstack));
635 qset_obst = xmalloc (sizeof (struct obstack));
637 obstack_init (name_obst);
638 obstack_init (qset_obst);
641 /* Cleanup the name module */
642 void pto_name_cleanup (void)
644 DBGPRINT (3, (stdout, "%s\n", __FUNCTION__));
645 obstack_free (name_obst, NULL);
646 obstack_free (qset_obst, NULL);
648 memset (name_obst, 0x00, sizeof (struct obstack));
649 memset (qset_obst, 0x00, sizeof (struct obstack));
661 Revision 1.19 2006/12/13 19:46:47 beck
662 rename type entity into ir_entity
664 Revision 1.18 2006/01/13 22:56:21 beck
665 renamed all types 'type' to 'ir_type'
667 Revision 1.17 2005/12/16 16:59:54 grund
668 *** empty log message ***
670 Revision 1.16 2005/12/05 12:19:54 beck
671 added missing include <assert.h> (not anymore included in libFirm)
673 Revision 1.15 2005/03/02 10:14:38 beck
674 placed a return on all execution pathes
676 Revision 1.14 2005/02/17 08:45:38 liekweg
677 Don't return a value for an invalid descriptor
679 Revision 1.13 2005/02/11 10:21:28 beck
680 get_entry now always returns a value
682 Revision 1.12 2005/01/14 14:13:56 liekweg
683 fix gnu extension, fix fprintf's, fix allocs
685 Revision 1.11 2005/01/05 14:25:54 beck
686 renames all is_x*_type() functions to is_X*_type() to prevent name clash with EDG fronten
688 Revision 1.10 2004/12/22 14:43:14 beck
689 made allocations C-like
691 Revision 1.9 2004/12/21 15:34:09 beck
692 removed C99 constructs
696 Revision 1.8 2004/12/15 13:30:30 liekweg
697 use DBGEXE correctly; print yet nicer names
699 Revision 1.7 2004/12/15 09:18:18 liekweg
702 Revision 1.6 2004/12/06 12:52:09 liekweg
705 Revision 1.4 2004/11/30 15:49:27 liekweg
708 Revision 1.3 2004/11/30 14:47:54 liekweg
709 fix initialisation; do correct iteration
711 Revision 1.2 2004/11/24 14:53:56 liekweg
714 Revision 1.1 2004/11/18 16:37:34 liekweg