add docu and prototype for find_value()
[libfirm] / ir / ana2 / pto_name.c
index 4d47eb5..50cfec7 100644 (file)
@@ -8,12 +8,12 @@
   Modified by:
   Created:     Sat Nov 13 19:35:27 CET 2004
   CVS-ID:      $Id$
-  Copyright:   (c) 1999-2004 Universität Karlsruhe
+  Copyright:   (c) 1999-2004 Universitt Karlsruhe
   Licence:     This file is protected by the GPL -  GNU GENERAL PUBLIC LICENSE.
 */
 
 # ifdef HAVE_CONFIG_H
-#  include <config.h>
+#  include "config.h"
 # endif
 
 /*
 # include "pto_name.h"
 # include "pto_util.h"
 
+#include <assert.h>
+
+#ifdef HAVE_STRING_H
 # include <string.h>            /* for memcpy */
+#endif
 # include <obstack.h>
 # include <errno.h>
 
@@ -33,6 +37,7 @@
 # include "xmalloc.h"
 
 # include "pto_debug.h"
+# include "gnu_ext.h"
 
 /* Local Defines: */
 # define obstack_chunk_alloc xmalloc
@@ -50,27 +55,166 @@ static desc_t *all_descs = NULL;
 
 static int name_id = 0;
 
+# define PTO_COLOR
+
+# ifdef PTO_COLOR
+static int last_col_idx = 0;
+
 /* Local Prototypes: */
+static int pto_name_alloc_color (desc_t*);
+static void pto_name_set_color (desc_t*, int);
+# endif /* defined PTO_COLOR */
 
 /* ===================================================
    Local Implementation:
    =================================================== */
+# ifdef PTO_COLOR
+/* set a nice color to an object descriptor */
+static void pto_name_set_obj_color (obj_desc_t *obj_desc, int col_idx)
+{
+  int i;
+
+  for (i = 0; i < obj_desc->n_fields; i ++) {
+    qset_t *ptos = obj_desc->values [i];
+
+    desc_t *tgt = (desc_t*) qset_start (ptos);
+
+    while (NULL != tgt) {
+      pto_name_set_color (tgt, col_idx);
+
+      tgt = (desc_t*) qset_next (ptos);
+    }
+  }
+}
+
+/* set a nice color to an array descriptor */
+static void pto_name_set_arr_color (arr_desc_t *arr_desc, int col_idx)
+{
+  qset_t *ptos = arr_desc->value;
+
+  desc_t *tgt = (desc_t*) qset_start (ptos);
+
+  while (NULL != tgt) {
+    pto_name_set_color (tgt, col_idx);
+
+    tgt = (desc_t*) qset_next (ptos);
+  }
+}
+
+/* set a nice color to a descriptor */
+static void pto_name_set_color (desc_t *desc, int col_idx)
+{
+  /* assert (0 == desc->col_idx); */
+
+  desc->col_idx = col_idx;
+
+  if (FALSE == desc->visit) {
+    desc->visit = TRUE;
+    if (object == desc->kind) {
+      pto_name_set_obj_color ((obj_desc_t*) desc, col_idx);
+    } else if (array == desc->kind) {
+      pto_name_set_arr_color ((arr_desc_t*) desc, col_idx);
+    }
+
+    desc->visit = FALSE;
+  }
+}
+
+
+/* allocate nice colors for an object descriptor */
+static int pto_name_alloc_obj_color (obj_desc_t *obj_desc)
+{
+  int i;
+  int col_idx = 0;
+
+  for (i = 0; (0 == col_idx) && (i < obj_desc->n_fields); i ++) {
+    qset_t *ptos = obj_desc->values [i];
+    desc_t *tgt = (desc_t*) qset_start (ptos);
+
+    while ((0 == col_idx) && (NULL != tgt)) {
+      col_idx = pto_name_alloc_color (tgt);
+
+      tgt = (desc_t*) qset_next (ptos);
+    }
+  }
+
+  return (col_idx);
+}
+
+/* allocate nice colors for an array descriptor */
+static int pto_name_alloc_arr_color (arr_desc_t *arr_desc)
+{
+  int col_idx = 0;
+
+  qset_t *ptos = arr_desc->value;
+
+  desc_t *tgt = (desc_t*) qset_start (ptos);
+
+  while ((NULL != tgt) && (0 == col_idx)) {
+    col_idx = pto_name_alloc_color (tgt);
+    tgt = (desc_t*) qset_next (ptos);
+  }
+
+  return (col_idx);
+}
+
+/* allocate nice colors for the given descriptor */
+static int pto_name_alloc_color (desc_t *desc)
+{
+  int col_idx = 0;
+
+  if (0 != desc->col_idx) {
+    return (desc->col_idx);
+  }
+
+  if (FALSE == desc->visit) {
+    desc->visit = TRUE;
+    if (object == desc->kind) {
+      col_idx = pto_name_alloc_obj_color ((obj_desc_t*) desc);
+    } else if (array == desc->kind) {
+      col_idx = pto_name_alloc_arr_color ((arr_desc_t*) desc);
+    }
+    desc->visit = FALSE;
+  }
+
+  if (0 == col_idx) {
+    col_idx = ++ last_col_idx;
+  }
+
+  pto_name_set_color (desc, col_idx);
+
+  return (col_idx);
+}
+
+/* allocate nice colors */
+static void pto_name_alloc_colors (void)
+{
+  desc_t *desc = all_descs;
+
+  while (NULL != desc) {
+    pto_name_alloc_color (desc);
+
+    desc = desc->prev;
+  }
+}
+# endif /* defined PTO_COLOR */
+
 /* See whether the given entity is a field. */
 static int is_field (entity *ent)
 {
-  type *tp = get_entity_type (ent);
+  ir_type *tp = get_entity_type (ent);
 
-  if (is_primitive_type (tp) || is_pointer_type (tp)) {
-    /* actually, we could get by by restricting ourselves to pointer types */
+  if (is_Primitive_type (tp) || is_Pointer_type (tp)) {
+    /* actually, we don't get by by restricting ourselves to pointer types */
     return (TRUE);
   } else {
     return (FALSE);
   }
 }
 
-/* Helper to collect_fields(type*): collect all fields of the given
+/* Helper to collect_fields(ir_type*): collect all fields of the given
   clazz and its super classes into the given obstack. */
-static void _collect_fields (type *clazz, struct obstack *obst)
+static void _collect_fields (ir_type *clazz, struct obstack *obst)
 {
   int n_members = get_class_n_members (clazz);
   int n_supers  = get_class_n_supertypes (clazz);
@@ -87,7 +231,7 @@ static void _collect_fields (type *clazz, struct obstack *obst)
   }
 
   for (i = 0; i < n_supers; i ++) {
-    type *s_clazz = get_class_supertype (clazz, i);
+    ir_type *s_clazz = get_class_supertype (clazz, i);
 
     _collect_fields (s_clazz, obst);
   }
@@ -95,38 +239,42 @@ static void _collect_fields (type *clazz, struct obstack *obst)
 
 /* Collect the fields of the given class and its super classes into an array.
   The last entry of the array is written NULL. */
-static entity **collect_fields (type *clazz)
+static entity **collect_fields (ir_type *clazz)
 {
+  struct obstack obst;
+  int n_fields;
+  entity ** fields;
+  void *tmp;
+
   if (NULL != get_type_link (clazz)) {
     DBGPRINT (3, (stdout, "%s: reusing field list for \"%s\"\n",
-                  __FUNCTION__, get_type_name (clazz)));
+                  __FUNCTION__,
+                  get_type_name (clazz)));
 
     return ((entity **) get_type_link (clazz));
   } else {
     DBGPRINT (2, (stdout, "%s: new field list for \"%s\"\n",
-                  __FUNCTION__, get_type_name (clazz)));
+                  __FUNCTION__,
+                  get_type_name (clazz)));
   }
 
-  struct obstack obst;
-
   obstack_init (&obst);
 
   _collect_fields (clazz, &obst);
 
   /* append terminating NULL */
-  int *the_null = NULL;
-  obstack_ptr_grow (&obst, the_null);
+  obstack_ptr_grow (&obst, NULL);
 
-  int n_fields = obstack_object_size (&obst) / sizeof (void*);
+  n_fields = obstack_object_size (&obst) / sizeof (void*);
 
-  entity ** fields = (entity**) NALLOC (n_fields * sizeof (entity*));
-  void *tmp = obstack_finish (&obst);
+  fields = NALLOC (n_fields * sizeof (entity*));
+  tmp = obstack_finish(&obst);
 
   memcpy (fields, tmp, n_fields * sizeof (entity*));
 
   obstack_free (&obst, NULL);
 
-  set_type_link (clazz, (void*) fields);
+  set_type_link (clazz, fields);
 
   return (fields);
 }
@@ -134,8 +282,12 @@ static entity **collect_fields (type *clazz)
 /* Write the intro text for a name dump into the given stream */
 static void pto_name_dump_start (FILE *stream)
 {
+# ifdef PTO_COLOR
+  pto_name_alloc_colors ();
+# endif /* defined PTO_COLOR */
+
   fprintf (stream, "digraph \"Names\" {\n");
-  fprintf (stream, "\tgraph [rankdir=\"LR\", ordering=\"out\"];\n");
+  fprintf (stream, "\tgraph [rankdir=\"LR\", ordering=\"out\", size=\"11,7\", rotate=\"90\"];\n");
   fprintf (stream, "\tnode [shape=\"record\", style=\"filled\"];\n");
   fprintf (stream, "\tedge [color=\"black\"];\n");
   fprintf (stream, "\n");
@@ -150,23 +302,40 @@ static void pto_name_dump_finish (FILE *stream)
 /* Write a node for the given descriptor into the given stream */
 static void pto_name_dump_desc (desc_t *desc, FILE *stream)
 {
-  type *tp = desc->tp;
+  ir_type *tp = desc->tp;
   const char *tp_name = get_type_name (tp);
+  ir_node *nd;
 
   fprintf (stream, "\t/* %s \"%s\" */\n",
            object == desc->kind ? "Object" : "Array",
            tp_name);
 
-  fprintf (stream, "\tdesc_%i [label=\"<HEAD>type=\\\"%s\\\"",
-           desc->id,
+  fprintf (stream, "\tdesc_%i [label=\"<HEAD>type \\[%i\\]",
+           desc->id, desc->id);
+
+  if (-1 != desc->ctx) {
+    fprintf (stream, ", ctx = %i", desc->ctx);
+  } else {
+    fprintf (stream, " (global)");
+  }
+
+  fprintf (stream, "\\lname=\\\"%s\\\"",
            tp_name);
 
-  ir_node *nd = desc->node;
+  nd = desc->node;
 
   if (NULL != nd) {
-    fprintf (stream, "|<NODE>node=%s\\[%li\\]",
+    ir_graph *graph = get_irn_irg (nd);
+    entity *method = get_irg_entity (graph);
+    const char *ent_name = get_entity_name (method);
+    const char *own_name = get_type_name (get_entity_owner (method));
+
+    fprintf (stream, "\\lnode=%s\\[%li\\]",
              get_op_name (get_irn_op (nd)),
              get_irn_node_nr (nd));
+    fprintf (stream, "\\lgraph=\\\"%s.%s\\\"",
+             own_name,
+             ent_name);
   }
 
   if (desc->kind == object) {
@@ -174,19 +343,71 @@ static void pto_name_dump_desc (desc_t *desc, FILE *stream)
 
     int i;
     for (i = 0; i < obj_desc->n_fields; i ++) {
-      const char *ent_name = get_entity_name (obj_desc->fields [i]);
+      entity *field = obj_desc->fields [i];
 
-      fprintf (stream, "|<%i>%s", i, ent_name);
+      if (is_Pointer_type (get_entity_type (field))) {
+        const char *ent_name = get_entity_name (field);
+
+        fprintf (stream, "|<%i>%s", i, ent_name);
+      }
     }
   } else if (array == desc->kind) {
-    arr_desc_t *arr_desc = (arr_desc_t*) desc;
-
     fprintf (stream, "|<arr>[]");
   } else {
     assert (0 && "invalid descriptor");
   }
 
-  fprintf (stream, "\"];\n");
+  /* end label string */
+  fprintf (stream, "\"");
+
+# ifdef PTO_COLOR
+  {
+    const char *fontcolor;
+    int col_idx = desc->col_idx;
+    float hue = (float) col_idx / (float) last_col_idx;
+    float sat = 1.000f;            /* 0.300 .. 1.000 */
+    float val = 0.800f;            /* 0.300 .. 1.000 */
+
+  # define MAX_COLORS 12
+    if (last_col_idx > MAX_COLORS) {
+      /* too many colors ... vary value too */
+      float div = (float) MAX_COLORS / (float) last_col_idx;
+
+      sat = (div * ((col_idx / MAX_COLORS)));
+      val = (div * ((col_idx / MAX_COLORS)));
+
+      col_idx = col_idx % MAX_COLORS;
+      hue = (float) col_idx / (float) MAX_COLORS;
+
+      // re-adjust sat and val
+      {
+        const float sat_min = 0.200f; /* 0.200 .. 0.400 */
+        const float val_min = 0.300f; /* 0.300 .. 0.400 */
+
+        sat = sat_min + ((1.0f - sat_min) * sat);
+        val = val_min + ((1.0f - val_min) * val);
+      }
+    }
+  # undef MAX_COLORS
+
+    fprintf (stream, ", color=\"%01.3f, %01.3f, %01.3f\"", hue, sat, val);
+
+    if ((hue > 0.3) && (sat < 0.5)) {
+      fontcolor = "white";
+    } else if (sat < 0.4) {
+      fontcolor = "white";
+    } else {
+      fontcolor = "black";
+    }
+
+    fprintf (stream, ", fontcolor=\"%s\"", fontcolor);
+  }
+# else /* if defined PTO_COLOR */
+  fprintf (stream, ", color=\"lightgrey\"");
+# endif /* defined PTO_COLOR */
+
+  /* end attributes */
+  fprintf (stream, "];\n");
   fprintf (stream, "\n");
 
   /* now the edges */
@@ -240,29 +461,31 @@ qset_t *get_entry (desc_t *desc, entity *ent)
     }
 
     assert (0 && "entry not found");
-  } else if (desc->kind = array) {
+  } else if (desc->kind == array) {
     arr_desc_t *arr_desc = (arr_desc_t*) desc;
 
     return (arr_desc->value);
   } else {
     assert (0 && "invalid descriptor");
   }
+  return NULL;
 }
 
 
 /* get a new descriptor for the given type at the given node */
-desc_t *new_name (type *tp, ir_node *node)
+desc_t *new_name (ir_type *tp, ir_node *node, int ctx)
 {
   desc_t *desc = NULL;
 
-  assert ((is_class_type (tp) || is_array_type (tp)) && "unsuitable type");
+  assert ((is_Class_type (tp) || is_Array_type (tp)) && "unsuitable type");
 
-  DBGPRINT (2, (stdout, "%s: new name for type \"%s\"\n", __FUNCTION__,
+  DBGPRINT (2, (stdout, "%s: new name for type \"%s\"\n",
+                __FUNCTION__,
                 get_type_name (tp)));
   fflush (stdout);
 
-  if (is_class_type (tp)) {
-    obj_desc_t *obj_desc = (obj_desc_t*) NALLOC (sizeof (obj_desc_t));
+  if (is_Class_type (tp)) {
+    obj_desc_t *obj_desc = NALLOC (sizeof (obj_desc_t));
     int i;
     int n_fields;
 
@@ -274,14 +497,14 @@ desc_t *new_name (type *tp, ir_node *node)
     }
 
     obj_desc->n_fields = n_fields;
-    obj_desc->values = (qset_t**) NALLOC (n_fields * sizeof (qset_t));
+    obj_desc->values = (qset_t**) NALLOC (n_fields * sizeof (qset_t*));
 
     for (i = 0; i < n_fields; i ++) {
       obj_desc->values [i] = qset_new (N_INITIAL_OJBS, qset_obst);
     }
 
     desc = (desc_t*) obj_desc;
-  } else if (is_array_type (tp)) {
+  } else if (is_Array_type (tp)) {
     arr_desc_t *arr_desc = (arr_desc_t*) NALLOC (sizeof (arr_desc_t));
 
     arr_desc->kind = array;
@@ -290,11 +513,14 @@ desc_t *new_name (type *tp, ir_node *node)
     desc = (desc_t*) arr_desc;
   }
 
-  desc->id   = name_id ++;
-  desc->tp   = tp;
-  desc->node = node;
+  desc->id    = name_id ++;
+  desc->col_idx = 0;
+  desc->tp    = tp;
+  desc->visit = FALSE;
+  desc->ctx   = ctx;
+  desc->node  = node;
 
-  desc->prev = all_descs;
+  desc->prev  = all_descs;
   all_descs = desc;
 
   return (desc);
@@ -309,11 +535,16 @@ desc_t *new_ent_name (entity *ent)
 {
   int i;
   int missing = TRUE;
-  type *tp = get_entity_type (ent);
+  ir_type *tp = get_entity_type (ent);
 
-  assert (is_pointer_type (tp));
+  assert (is_Pointer_type (tp));
   tp = get_pointer_points_to_type (tp);
-  assert (is_class_type (tp));
+  assert (is_Class_type (tp));
+
+  DBGPRINT (2, (stdout, "%s: new name for entity \"%s\"\n",
+                __FUNCTION__,
+                get_entity_name (ent)));
+  DBGEXE (2, (fflush (stdout)));
 
   assert (((allocation_static == get_entity_allocation (ent)) ||
            (allocation_automatic == get_entity_allocation (ent))) &&
@@ -323,6 +554,9 @@ desc_t *new_ent_name (entity *ent)
     obj_glob = (obj_desc_t*) NALLOC (sizeof (obj_desc_t));
 
     obj_glob->id   = name_id ++;
+    obj_glob->ctx  = -1;
+    obj_glob->col_idx = 0;
+    obj_glob->visit = FALSE;
     obj_glob->kind = object;
     obj_glob->tp   = get_glob_type ();
     obj_glob->node = NULL;
@@ -391,9 +625,9 @@ void pto_dump_names (const char *name)
 }
 
 /* Initialise the name module */
-void pto_name_init ()
+void pto_name_init (void)
 {
-  DBGPRINT (3, (stdout, "(%s:%i) %s\n", __FILE__, __LINE__, __FUNCTION__));
+  DBGPRINT (3, (stdout, "%s\n", __FUNCTION__));
   assert (NULL == name_obst);
   assert (NULL == qset_obst);
 
@@ -405,9 +639,9 @@ void pto_name_init ()
 }
 
 /* Cleanup the name module */
-void pto_name_cleanup ()
+void pto_name_cleanup (void)
 {
-  DBGPRINT (3, (stdout, "(%s:%i) %s\n", __FILE__, __LINE__, __FUNCTION__));
+  DBGPRINT (3, (stdout, "%s\n", __FUNCTION__));
   obstack_free (name_obst, NULL);
   obstack_free (qset_obst, NULL);
 
@@ -424,6 +658,47 @@ void pto_name_cleanup ()
 \f
 /*
   $Log$
+  Revision 1.18  2006/01/13 22:56:21  beck
+  renamed all types 'type' to 'ir_type'
+
+  Revision 1.17  2005/12/16 16:59:54  grund
+  *** empty log message ***
+
+  Revision 1.16  2005/12/05 12:19:54  beck
+  added missing include <assert.h> (not anymore included in libFirm)
+
+  Revision 1.15  2005/03/02 10:14:38  beck
+  placed a return on all execution pathes
+
+  Revision 1.14  2005/02/17 08:45:38  liekweg
+  Don't return a value for an invalid descriptor
+
+  Revision 1.13  2005/02/11 10:21:28  beck
+  get_entry now always returns a value
+
+  Revision 1.12  2005/01/14 14:13:56  liekweg
+  fix gnu extension, fix fprintf's, fix allocs
+
+  Revision 1.11  2005/01/05 14:25:54  beck
+  renames all is_x*_type() functions to is_X*_type() to prevent name clash with EDG fronten
+
+  Revision 1.10  2004/12/22 14:43:14  beck
+  made allocations C-like
+
+  Revision 1.9  2004/12/21 15:34:09  beck
+  removed C99 constructs
+  make const float
+  add default return
+
+  Revision 1.8  2004/12/15 13:30:30  liekweg
+  use DBGEXE correctly; print yet nicer names
+
+  Revision 1.7  2004/12/15 09:18:18  liekweg
+  pto_name.c
+
+  Revision 1.6  2004/12/06 12:52:09  liekweg
+  colorize name dump
+
   Revision 1.4  2004/11/30 15:49:27  liekweg
   include 'dump'