[project @ 2000-04-05 10:06:36 by simonmar]
authorsimonmar <unknown>
Wed, 5 Apr 2000 10:06:36 +0000 (10:06 +0000)
committersimonmar <unknown>
Wed, 5 Apr 2000 10:06:36 +0000 (10:06 +0000)
Add new profiling tool (probably non-working so far).

36 files changed:
ghc/utils/prof/Makefile [new file with mode: 0644]
ghc/utils/prof/cgprof/Makefile [new file with mode: 0644]
ghc/utils/prof/cgprof/README [new file with mode: 0644]
ghc/utils/prof/cgprof/cgprof.c [new file with mode: 0644]
ghc/utils/prof/cgprof/cgprof.h [new file with mode: 0644]
ghc/utils/prof/cgprof/daVinci.c [new file with mode: 0644]
ghc/utils/prof/cgprof/daVinci.h [new file with mode: 0644]
ghc/utils/prof/cgprof/main.c [new file with mode: 0644]
ghc/utils/prof/cgprof/matrix.c [new file with mode: 0644]
ghc/utils/prof/cgprof/matrix.h [new file with mode: 0644]
ghc/utils/prof/cgprof/symbol.c [new file with mode: 0644]
ghc/utils/prof/cgprof/symbol.h [new file with mode: 0644]
ghc/utils/prof/ghcprof.prl [new file with mode: 0644]
ghc/utils/prof/icons/absdelta.xbm [new file with mode: 0644]
ghc/utils/prof/icons/absolute.xbm [new file with mode: 0644]
ghc/utils/prof/icons/comm.xbm [new file with mode: 0644]
ghc/utils/prof/icons/commslack.xbm [new file with mode: 0644]
ghc/utils/prof/icons/comp.xbm [new file with mode: 0644]
ghc/utils/prof/icons/compress.xbm [new file with mode: 0644]
ghc/utils/prof/icons/compslack.xbm [new file with mode: 0644]
ghc/utils/prof/icons/delete.xbm [new file with mode: 0644]
ghc/utils/prof/icons/help.xbm [new file with mode: 0644]
ghc/utils/prof/icons/hrel.xbm [new file with mode: 0644]
ghc/utils/prof/icons/hrelslack.xbm [new file with mode: 0644]
ghc/utils/prof/icons/jump.xbm [new file with mode: 0644]
ghc/utils/prof/icons/mycomm.xbm [new file with mode: 0644]
ghc/utils/prof/icons/oxpara.xbm [new file with mode: 0644]
ghc/utils/prof/icons/percent.xbm [new file with mode: 0644]
ghc/utils/prof/icons/reldelta.xbm [new file with mode: 0644]
ghc/utils/prof/icons/sync.xbm [new file with mode: 0644]
ghc/utils/prof/icons/time.xbm [new file with mode: 0644]
ghc/utils/prof/icons/time1.xbm [new file with mode: 0644]
ghc/utils/prof/icons/uncompress.xbm [new file with mode: 0644]
ghc/utils/prof/icons/undo.xbm [new file with mode: 0644]
ghc/utils/prof/icons/wait.xbm [new file with mode: 0644]
ghc/utils/prof/icons/weightdelta.xbm [new file with mode: 0644]

diff --git a/ghc/utils/prof/Makefile b/ghc/utils/prof/Makefile
new file mode 100644 (file)
index 0000000..9afbfdf
--- /dev/null
@@ -0,0 +1,46 @@
+#-----------------------------------------------------------------------------
+# $Id: Makefile,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+#
+# (c) The GHC Team, 2000
+#
+
+TOP=../..
+include $(TOP)/mk/boilerplate.mk
+
+INSTALLING=1
+
+ifeq "$(INSTALLING)" "1"
+SUBDIRS = cgprof
+endif
+
+SCRIPT_SUBST_VARS= \
+ FPTOOLS_TOP_ABS \
+ INSTALLING \
+ TMPDIR \
+ TARGETPLATFORM
+
+INSTALLED_SCRIPT_PROG  = ghcprof
+INPLACE_SCRIPT_PROG    = ghcprof-inplace
+
+ifeq "$(INSTALLING)" "1"
+SCRIPT_PROG    =  $(INSTALLED_SCRIPT_PROG)
+else
+SCRIPT_PROG    =  $(INPLACE_SCRIPT_PROG)
+endif
+
+ifneq "$(BIN_DIST)" "1"
+SCRIPT_SUBST_VARS += libdir
+endif
+
+# don't recurse on 'make install'
+#
+ifeq "$(INSTALLING)" "1"
+all clean veryclean maintainer-clean ::
+       $(MAKE) INSTALLING=0 BIN_DIST=0 $(MFLAGS) $@
+endif
+
+INTERP          = perl
+SCRIPT_OBJS    = ghcprof.prl
+INSTALL_SCRIPTS += $(SCRIPT_PROG)
+
+include $(TOP)/mk/target.mk
diff --git a/ghc/utils/prof/cgprof/Makefile b/ghc/utils/prof/cgprof/Makefile
new file mode 100644 (file)
index 0000000..4471a37
--- /dev/null
@@ -0,0 +1,15 @@
+#-----------------------------------------------------------------------------
+# $Id: Makefile,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+#
+# (c) The GHC Team, 2000
+#
+
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+
+C_PROG = cgprof
+INSTALL_LIBEXECS=$(C_PROG)
+
+SRC_CC_OPTS += -I$(GHC_INCLUDE_DIR)
+
+include $(TOP)/mk/target.mk
diff --git a/ghc/utils/prof/cgprof/README b/ghc/utils/prof/cgprof/README
new file mode 100644 (file)
index 0000000..2c4ca16
--- /dev/null
@@ -0,0 +1,7 @@
+
+Please read the instructions in the section `Introduction - Using the 
+profiling tool' before you begin:
+
+http://www.dcs.warwick.ac.uk/people/academic/Stephen.Jarvis/profiler/index.html
+
+This contains all the necessary compilation instructions etc.
diff --git a/ghc/utils/prof/cgprof/cgprof.c b/ghc/utils/prof/cgprof/cgprof.c
new file mode 100644 (file)
index 0000000..838bd5d
--- /dev/null
@@ -0,0 +1,1293 @@
+/* ------------------------------------------------------------------------
+ * $Id: cgprof.c,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+ *                                                                     
+ *     Copyright (C) 1995-2000 University of Oxford
+ *                                                                     
+ * Permission to use, copy, modify, and distribute this software,
+ * and to incorporate it, in whole or in part, into other software,
+ * is hereby granted without fee, provided that
+ *   (1) the above copyright notice and this permission notice appear in
+ *      all copies of the source code, and the above copyright notice
+ *      appear in clearly visible form on all supporting documentation
+ *      and distribution media;
+ *   (2) modified versions of this software be accompanied by a complete
+ *      change history describing author, date, and modifications made;
+ *      and
+ *   (3) any redistribution of the software, in original or modified
+ *      form, be without fee and subject to these same conditions.
+ * --------------------------------------------------------------------- */
+
+#include "config.h"
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "daVinci.h"
+#include "symbol.h"
+#include "cgprof.h"
+#include "matrix.h"
+
+/* -----------------------------------------------------------------------------
+ * Data structures
+ * -------------------------------------------------------------------------- */
+
+int                 raw_profile_next=0;
+int                 raw_profile_size=0;
+parsed_cost_object *raw_profile=NULL;
+
+/* -----------------------------------------------------------------------------
+ * Create/grow data sequence of raw profile data
+ * -------------------------------------------------------------------------- */
+
+void enlargeRawProfile() {
+
+  if (raw_profile_size==0) {
+    raw_profile_next = 0;
+    raw_profile_size = RAW_PROFILE_INIT_SIZE;
+    raw_profile      = calloc(raw_profile_size,sizeof(parsed_cost_object));
+  } else {
+    raw_profile_size += RAW_PROFILE_INIT_SIZE;
+    raw_profile       = realloc(raw_profile,
+                                raw_profile_size*sizeof(parsed_cost_object));
+  }
+  if (raw_profile==NULL) {
+    fprintf(stderr,"{enlargeRawProfile} unable to allocate %d elements",
+            raw_profile_size);
+    exit(1);
+  }
+}
+
+/* -----------------------------------------------------------------------------
+ * Function that adds two cost centers together
+ *
+ * This will be used to generate the inheretance profile.
+ * -------------------------------------------------------------------------- */
+
+void add_costs(object_cost *left, object_cost right) {
+  int i;
+
+  left->syncs         += right.syncs;
+  left->comp_max      += right.comp_max;
+  left->comp_avg      += right.comp_avg;
+  left->comp_min      += right.comp_min;
+  left->comm_max      += right.comm_max;
+  left->comm_avg      += right.comm_avg;
+  left->comm_min      += right.comm_min;
+  left->comp_idle_max += right.comp_idle_max;
+  left->comp_idle_avg += right.comp_idle_avg;
+  left->comp_idle_min += right.comp_idle_min;
+  left->hrel_max      += right.hrel_max;
+  left->hrel_avg      += right.hrel_avg;
+  left->hrel_min      += right.hrel_min;
+  if ((left->proc==NULL) || (right.proc==NULL)) {
+    fprintf(stderr,"Cost is null");
+    exit(0);
+  }
+}
+
+
+int ignore_function(char *fname) {
+  return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * GHC specific data structures
+ * -------------------------------------------------------------------------- */
+
+/* Globals */
+/* You will need to update these when you increase the number of */
+/*   cost centres, cost centre stacks, heap objects              */
+
+   #define MAX_IDENTIFIERS 2000 /* maximum number of identifiers */
+                                /* or size of matrix structure   */
+
+  /* make this dynamic */
+
+   #define MAX_TIME    100      /* Maximum serial time for heap profile */
+   #define MAX_SAMPLES 50       /* Maximum heap samples */
+
+                                /* To do: modify this to be dynamic */
+
+   #define MAX_STRING_SIZE 70
+   #define MAX_LINE_LENGTH 80
+   #define EOF (-1)
+
+/* Cost centre data structure */
+
+   struct cost_centre { char *name;
+                        char *module;
+                        char *group;
+   } _cc_;
+
+   typedef struct cost_centre cc_matrix[MAX_IDENTIFIERS];
+
+   //typedef struct cost_centre *cc_matrix;
+
+   typedef cc_matrix* p_cc_matrix;
+   typedef char* MY_STRING;
+
+/* Heap sample structure */
+
+   struct heap_sample { 
+                        int count; /* heap_sample */
+   };
+
+   typedef struct heap_sample heap_sample_matrix[MAX_IDENTIFIERS];
+   typedef heap_sample_matrix* p_heap_sample_matrix;
+
+/* Cost centre stack data structure */
+
+   struct cost_centre_stack { 
+                      int cc;
+                      int ccs;
+                      int scc;   /* scc_sample  */
+                      int ticks; /* scc_sample  */
+                      int bytes; /* scc_sample  */
+                      p_heap_sample_matrix hsm; /* heap_sample */
+   };
+
+   typedef struct cost_centre_stack ccs_matrix[MAX_IDENTIFIERS];
+   typedef ccs_matrix* p_ccs_matrix;
+
+/* Heap object data structure */
+
+   struct heap_object { int   type;            /* type of heap object */
+                        char* descriptor; 
+                        int   type_constr_ref; /* if present */
+                      };
+
+   typedef struct heap_object heap_object_matrix[MAX_IDENTIFIERS];
+   typedef heap_object_matrix* p_heap_object_matrix;
+
+/* Type constructor structure */
+
+   struct type_constr { char* module;
+                        char* name;
+                      };
+
+   typedef struct type_constr type_constr_matrix[MAX_IDENTIFIERS];
+   typedef type_constr_matrix* p_type_constr_matrix;
+
+/* Heap update structure */
+
+   struct heap_update_sample { int ccs;   /* associated cost centre stack */
+                               int ho;    /* associated heap object */
+                               int count; 
+                              };
+
+   typedef struct heap_update_sample heap_update_list[MAX_SAMPLES];
+   typedef heap_update_list* p_heap_update_list;
+
+   struct heap_update_record { int no_samples; /* Number of samples */
+                               p_heap_update_list acc_samples;
+                             };
+
+   typedef struct heap_update_record TheHeap[MAX_TIME];
+   typedef TheHeap* p_TheHeap;
+
+
+/* -----------------------------------------------------------------------------
+ * GHC specific functions
+ * -------------------------------------------------------------------------- */
+
+// Initialisation routines
+
+void initialise_heap_update_list(heap_update_list *m)
+{
+  int i;
+  for (i=0; i<MAX_SAMPLES;i++)
+  {
+    (*m)[i].ccs   = -1;
+    (*m)[i].ho    = -1;
+    (*m)[i].count    = -1;
+  }
+}
+
+void add_to_heap_update_list(heap_update_list *m, int ccs, int ho, int count, int pos)
+{
+  (*m)[pos].ccs    = ccs;
+  (*m)[pos].ho     = ho;
+  (*m)[pos].count    = count;
+}
+
+void initialise_TheHeap(TheHeap *h)
+{
+  int i;
+  for (i=0; i<MAX_TIME;i++)
+  {
+    heap_update_list *h_u_l;
+    h_u_l = (p_heap_update_list) malloc (sizeof(heap_update_list));
+    initialise_heap_update_list(h_u_l);
+    (*h)[i].acc_samples = h_u_l;
+    (*h)[i].no_samples   = 0;
+  }
+}
+
+void add_to_TheHeap(TheHeap *h, int time, int ccs, int ho, int count)
+{
+  add_to_heap_update_list((*h)[time].acc_samples,ccs,ho,count,(*h)[time].no_samples);
+  (*h)[time].no_samples++;
+}
+
+void initialise_cc_matrix(cc_matrix *m)
+{ 
+  int i;
+  char *blank="blank"; /* To do: Modify this terminator string */
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+    { 
+      (*m)[i].name =  (MY_STRING) malloc ((MAX_STRING_SIZE));
+      (*m)[i].module = (MY_STRING) malloc ((MAX_STRING_SIZE));
+      (*m)[i].group = (MY_STRING) malloc ((MAX_STRING_SIZE));
+
+      strcpy((*m)[i].name,blank); 
+      strcpy((*m)[i].module,blank);
+      strcpy((*m)[i].group,blank);  
+    }
+}
+
+void free_cc_matrix(cc_matrix *m)
+{
+  int i;
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+    {
+      free((*m)[i].name);
+      free((*m)[i].module);
+      free((*m)[i].group);
+    }
+    free(m);
+}
+
+void initialise_heap_object_matrix(heap_object_matrix *m)
+{
+  int i;
+  char *blank="blank"; /* To do: ditto */
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+  {
+    (*m)[i].type = -1;
+    (*m)[i].descriptor = (MY_STRING) malloc ((MAX_STRING_SIZE));
+    strcpy((*m)[i].descriptor,blank);
+    (*m)[i].type_constr_ref = -1; 
+  }
+}
+
+void initialise_type_constr_matrix(type_constr_matrix *m)
+{
+  int i;
+  char *blank="blank";
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+  {
+    (*m)[i].module = (MY_STRING) malloc ((MAX_STRING_SIZE));
+    (*m)[i].name   = (MY_STRING) malloc ((MAX_STRING_SIZE));
+    strcpy((*m)[i].module,blank);
+    strcpy((*m)[i].name,blank);
+  }
+}
+
+void initialise_heap_sample_matrix(heap_sample_matrix *m)
+{
+  int i;
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+  { (*m)[i].count = -1; }
+}
+
+void initialise_ccs_matrix(ccs_matrix *m)
+{ 
+  int i;
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+    { 
+      /* Stack heap samples */
+      heap_sample_matrix *hs_m;
+      hs_m = (p_heap_sample_matrix) malloc (sizeof(heap_sample_matrix));
+      initialise_heap_sample_matrix(hs_m);
+      (*m)[i].hsm = hs_m;
+      /* Stack scc samples */
+      (*m)[i].cc    = 0; 
+      (*m)[i].ccs   = 0;
+      (*m)[i].scc   = 0;
+      (*m)[i].ticks = 0; 
+      (*m)[i].bytes = 0; 
+    }
+}
+
+
+// Filling matrix routines
+
+char* StripDoubleQuotes(char* s) /* For fussy daVinci! */
+{
+  char *p = s;
+  char *tempchar;
+  char *empty="";
+  char *tempstring = (MY_STRING) malloc ((MAX_STRING_SIZE));
+  strcpy(tempstring,empty);
+  while (*p)
+  { if (*p!='"')
+    { tempchar = p; strncat(tempstring,p,1);
+     }
+    p++; 
+  }
+  return tempstring;
+}
+
+void fill_cc_matrix(cc_matrix *m,char* name,char* module,char* group,int i)
+{ 
+  if (i>MAX_IDENTIFIERS) 
+  {  fprintf(log,"Cost centre MAX_IDENTIFIERS exceeded: %i \n",i); exit(1); }
+  name = StripDoubleQuotes(name);
+  strcpy((*m)[i].name,name); 
+  module = StripDoubleQuotes(module);
+  strcpy((*m)[i].module,module);
+  group = StripDoubleQuotes(group);
+  strcpy((*m)[i].group,group);
+}
+
+void fill_ccs_matrix(ccs_matrix *m,int cc, int ccs, int scc, int ticks, int bytes, int h_o, int count, int i)
+{
+  heap_sample_matrix *hsm;
+
+  if ((*m)[i].cc == 0)  /* added for type 2 stack semantics, but should not */
+                        /* change behaviour of type 1 (apart from CAF:REP.  */
+  {
+    if (i>MAX_IDENTIFIERS) 
+    {  fprintf(log,"Cost centre stack MAX_IDENTIFIERS exceeded: %i \n",i); exit(1); }
+    hsm = (*m)[i].hsm;
+    (*m)[i].cc = cc; (*m)[i].ccs = ccs; 
+    (*m)[i].ticks = ticks; (*m)[i].bytes = bytes; (*m)[i].scc = scc;
+    (*hsm)[h_o].count = count;
+  }
+  else fprintf(log,"Ignoring redeclaration of stack %i\n",i);
+}
+
+void add_ccs_costs(ccs_matrix *m, int b,int c,int d,int x,int y,int h_o, int co)
+{
+  (*m)[c].scc    = (*m)[c].scc + d;
+  (*m)[c].ticks  = (*m)[c].ticks + x;
+  (*m)[c].bytes  = (*m)[c].bytes + y;
+}
+
+void add_heap_sample_costs(ccs_matrix *m, int b,int c,int d,int x,int y,int h_o, int co)
+{ 
+  heap_sample_matrix *hsm = (*m)[c].hsm;
+  if (((*hsm)[h_o].count)==-1)
+     (*hsm)[h_o].count = (*hsm)[h_o].count + co + 1; /* as init is -1 */
+  else 
+     (*hsm)[h_o].count = (*hsm)[h_o].count + co;
+}
+
+void add_heap_object(heap_object_matrix *m, int pos, int t, char* des, int tr)
+{
+  if (pos>MAX_IDENTIFIERS) 
+  {  fprintf(log,"Heap object MAX_IDENTIFIERS exceeded: %i \n",pos); exit(1); }
+  (*m)[pos].type = t;
+  strcpy((*m)[pos].descriptor,des);
+  (*m)[pos].type_constr_ref = tr;
+} 
+
+void add_type_constr_object(type_constr_matrix *m, int pos, char* mod, char* n)
+{
+  if (pos>MAX_IDENTIFIERS) 
+  {  fprintf(log,"Type constructor MAX_IDENTIFIERS exceeded: %i \n",pos); exit(1); }
+  strcpy((*m)[pos].module,mod);
+  strcpy((*m)[pos].name,n);
+}
+
+
+// Printing routines
+
+void print_heap_update_list(heap_update_list *m, int number)
+{
+  int i;
+  fprintf(log,"[");
+  for (i=0; i<number;i++)
+  {
+    fprintf(log," (%i,%i,%i) ",(*m)[i].ccs,(*m)[i].ho,(*m)[i].count);
+  }
+  fprintf(log,"]\n");
+}
+
+void print_TheHeap(TheHeap *h)
+{
+  int i;
+  fprintf(log,"The Heap\n========\n");
+  for (i=0; i<MAX_TIME;i++)
+  {
+    if ((*h)[i].no_samples>0)
+    {
+      fprintf(log,"Sample time %i, number of samples %i actual samples "
+                 ,i,(*h)[i].no_samples);
+      print_heap_update_list((*h)[i].acc_samples,(*h)[i].no_samples);
+    }
+  }
+}
+
+void PrintXaxis(FILE *HEAP_PROFILE, TheHeap *h)
+{
+  int i;
+  fprintf(HEAP_PROFILE," ");
+  for (i=0; i<MAX_TIME;i++)
+  {
+    if ((*h)[i].no_samples>0)
+       fprintf(HEAP_PROFILE,"%i ",i);
+  }
+}
+
+int FindSample(heap_update_list *m, int number, int element)
+{
+  int i;
+  for (i=0; i<number;i++)
+  {
+    if ((*m)[i].ho==element)
+        return ((*m)[i].count);
+  }
+  return 0;
+}
+
+void PrintSampleCosts(FILE *hfp, TheHeap *h, int element)
+{
+  int i;
+  int total = 0;
+  for (i=0; i<MAX_TIME;i++)
+  {
+    if ((*h)[i].no_samples>0)
+    {
+      total = total + FindSample((*h)[i].acc_samples,(*h)[i].no_samples,element);
+      fprintf(hfp," %i ",total);
+    }
+  }
+}
+
+void print_cc_matrix(cc_matrix *m)
+{ 
+  int i;
+  char *blank="blank";
+  fprintf(log,"Cost centre matrix\n");
+  fprintf(log,"==================\n");
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+    { if (strcmp((*m)[i].name,blank)!=0) 
+         fprintf(log,"%s %s %s\n",(*m)[i].name,(*m)[i].module,(*m)[i].group); }
+  fprintf(log,"\n");
+}
+
+void print_heap_object_matrix(FILE* hfp, TheHeap *h, heap_object_matrix *m)
+{
+  int i;
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+  { 
+    if (((*m)[i].type)!=-1)
+    {
+      fprintf(hfp,"Y%i set {",i);
+      /* if ((*m)[i].type==1) fprintf(hfp,"data_contr ");
+      if ((*m)[i].type==2) fprintf(hfp,"PAP ");
+      if ((*m)[i].type==3) fprintf(hfp,"thunk ");
+      if ((*m)[i].type==4) fprintf(hfp,"function ");
+      if ((*m)[i].type==5) fprintf(hfp,"dictionary ");
+      if ((*m)[i].type==1) 
+         fprintf(hfp,"%s %i ",(*m)[i].descriptor,(*m)[i].type_constr_ref);
+      else
+         fprintf(hfp,"%s ",(*m)[i].descriptor); */
+      PrintSampleCosts(hfp,h,i);
+      fprintf(hfp,"}\n");
+    }
+  }         
+}
+
+int number_of_heap_objects(heap_object_matrix *m)
+{
+  int i;
+  int count = 0;
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+  {
+    if (((*m)[i].type)!=-1) count++;
+  }
+  return count;
+}
+
+void names_of_heap_objects(FILE *hfp, heap_object_matrix *m)
+{
+  int i;
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+  {
+    if (((*m)[i].type)!=-1) 
+      fprintf(hfp,"Y%i ",i);
+  }
+  fprintf(hfp,"\n");
+}
+
+void names_and_colour_assignment(FILE *hfp, heap_object_matrix *m)
+{
+  int i;
+  int colour=0;
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+  {
+    if (((*m)[i].type)!=-1) 
+    {
+      switch(colour)
+      {
+        case 0 : fprintf(hfp,"%s \t Y%i \t red \t fdiagonal1\n",(*m)[i].descriptor,i); 
+                 colour++; break;
+        case 1 : fprintf(hfp,"%s \t Y%i \t blue \t fdiagonal1\n",(*m)[i].descriptor,i);
+                 colour++; break;
+        case 2 : fprintf(hfp,"%s \t Y%i \t green \t fdiagonal1\n",(*m)[i].descriptor,i);
+                 colour++; break;
+        case 3 : fprintf(hfp,"%s \t Y%i \t yellow \t fdiagonal1\n",(*m)[i].descriptor,i);
+                 colour++; break;
+        case 4 : fprintf(hfp,"%s \t Y%i \t pink \t fdiagonal1\n",(*m)[i].descriptor,i);
+                 colour++; break;
+        case 5 : fprintf(hfp,"%s \t Y%i \t goldenrod \t fdiagonal1\n",(*m)[i].descriptor,i);
+                 colour++; break;
+        case 6 : fprintf(hfp,"%s \t Y%i \t orange \t fdiagonal1\n",(*m)[i].descriptor,i);
+                 colour++; break;
+        default: fprintf(hfp,"%s \t Y%i \t purple \t fdiagonal1\n",(*m)[i].descriptor,i);
+                 colour=0; break;
+      }
+    }
+  }
+}
+
+void print_type_constr_matrix(type_constr_matrix *m)
+{
+  int i;
+  char *blank="blank";
+  fprintf(log,"Type constructor matrix\n");
+  fprintf(log,"=======================\n");
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+  {
+    if (strcmp((*m)[i].name,blank)!=0)
+         fprintf(log,"%i %s %s\n",i,(*m)[i].module,(*m)[i].name);
+  }
+}
+
+void print_heap_sample_matrix(heap_sample_matrix *m)
+{
+  int i;
+  fprintf(log,"HeapSamples[");
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+  {
+    if ((*m)[i].count!=-1) fprintf(log,"(%i,%i),",i,(*m)[i].count);
+  }
+  fprintf(log,"]\n");
+}
+
+void print_ccs_matrix(ccs_matrix *m)
+{ 
+  int i;
+  fprintf(log,"Cost centre stack matrix\n");
+  fprintf(log,"========================\n");
+  for (i=0; i<MAX_IDENTIFIERS; i++)
+  {  if ((*m)[i].cc!=0)
+     {
+       fprintf(log,"%i %i %i %i %i \n",(*m)[i].cc,(*m)[i].ccs,(*m)[i].scc,
+                               (*m)[i].ticks,(*m)[i].bytes); 
+     } 
+  }
+  fprintf(log,"\n");
+}
+
+
+/* No longer used */
+
+void FormStack(ccs_matrix *m, cc_matrix *n, int i, char s[])
+{
+  int j = i;
+  if ((*m)[j].cc != 0)
+  {
+    strcat(s,(*n)[(*m)[j].cc].name);
+    strcat(s," ");
+    while ((*m)[j].ccs != (-1))
+    {
+      strcat(s,(*n)[(*m)[(*m)[j].ccs].cc].name);
+      strcat(s,",");
+      j = (*m)[j].ccs;
+    }
+  }
+  else fprintf(log,"ERROR: Form Stack %i\n",i);
+}
+
+/* This version, which is used, adds the module and group name to the cost centre name*/
+/* This means the cost centre name remains unique when it is textualised and fed into */
+/* daVinci. It also allows the module and group name to be extracted at the display   */
+/* level */
+
+void FormStack2(ccs_matrix *m, cc_matrix *n, int i, char s[])
+{
+  int j = i;
+  if ((*m)[j].cc != 0)
+  {
+    strcat(s,(*n)[(*m)[j].cc].name);
+    strcat(s,"&");
+    strcat(s,(*n)[(*m)[j].cc].module);
+    strcat(s,"&");
+    strcat(s,(*n)[(*m)[j].cc].group);
+    strcat(s," ");
+    while ((*m)[j].ccs != (-1))
+    {
+      strcat(s,(*n)[(*m)[(*m)[j].ccs].cc].name);
+      strcat(s,"&");
+      strcat(s,(*n)[(*m)[(*m)[j].ccs].cc].module);
+      strcat(s,"&");
+      strcat(s,(*n)[(*m)[(*m)[j].ccs].cc].group);
+      strcat(s,",");
+      j = (*m)[j].ccs;
+    }
+  }
+  else fprintf(log,"ERROR: Form Stack %i\n",i);
+}
+
+void PrintStack(ccs_matrix *m, cc_matrix *n, int i)
+{
+  char    stack[MAX_PROFILE_LINE_LENGTH];
+  int j = i;
+  if ((*m)[j].cc != 0)
+  {
+    fprintf(log,"<"); 
+    fprintf(log,"%s,",(*n)[(*m)[j].cc].name);
+    while ((*m)[j].ccs != (-1))
+    {
+      fprintf(log,"%s,",(*n)[(*m)[(*m)[j].ccs].cc].name);
+      j = (*m)[j].ccs;
+    }
+    fprintf(log,"> ");
+    fprintf(log,"%i scc %i ticks %i bytes  ",
+            (*m)[i].scc,(*m)[i].ticks,(*m)[i].bytes);
+    print_heap_sample_matrix((*m)[i].hsm);
+  }
+  else
+  { /* fprintf(log,"empty stack\n"); */ }
+}
+
+int CountStacks(ccs_matrix *m)
+{
+  int j;
+  int count = 0;
+  for (j=0; j<MAX_IDENTIFIERS;j++) if ((*m)[j].cc != 0) count++;
+  return count;
+}
+
+void PrintAllStacks(ccs_matrix *m, cc_matrix *n)
+{
+  int i;
+  fprintf(log,"Stacks\n======\n");
+  for (i=0;i<MAX_IDENTIFIERS;i++) { PrintStack(m,n,i); }
+}
+
+
+/* -----------------------------------------------------------------------------
+ * TCL Heap profile generator
+ * -------------------------------------------------------------------------- */
+
+void produce_HEAP_PROFILE(FILE *HEAP_PROFILE, TheHeap *th, heap_object_matrix *ho_m)
+{
+  // First the header information 
+  fprintf(HEAP_PROFILE,"#!/home/sj/blt2.4o/src/bltwish\n");
+  fprintf(HEAP_PROFILE,"package require BLT\n");
+  fprintf(HEAP_PROFILE,"if { $tcl_version >= 8.0 } {\n");
+  fprintf(HEAP_PROFILE,"\t \t namespace import blt::*\n");
+  fprintf(HEAP_PROFILE,"namespace import -force blt::tile::*\n");
+  fprintf(HEAP_PROFILE,"}\n");
+  fprintf(HEAP_PROFILE,"source scripts/demo.tcl\n");
+  fprintf(HEAP_PROFILE,"proc FormatXTicks { w value } {\n");
+  fprintf(HEAP_PROFILE,"\t \t set index [expr round($value)]\n");
+  fprintf(HEAP_PROFILE,"\t \t if { $index != $value } {\n");
+  fprintf(HEAP_PROFILE,"\t \t \t return $value\n");
+  fprintf(HEAP_PROFILE,"\t \t}\n");
+  fprintf(HEAP_PROFILE,"incr index -1\n");
+
+  // Now the code to generate the units in the X axis
+
+  fprintf(HEAP_PROFILE,"set name [lindex { ");
+  PrintXaxis(HEAP_PROFILE,th);
+  fprintf(HEAP_PROFILE," } $index]\n");
+
+  fprintf(HEAP_PROFILE,"return $name\n");
+  fprintf(HEAP_PROFILE,"}\n");
+  
+  // more general graph stuff 
+
+  fprintf(HEAP_PROFILE,"source scripts/stipples.tcl\n");
+  fprintf(HEAP_PROFILE,"image create photo bgTexture -file ./images/chalk.gif\n");
+  fprintf(HEAP_PROFILE,"option add *Button.padX                        5\n");
+  fprintf(HEAP_PROFILE,"option add *tile                       bgTexture\n");
+  fprintf(HEAP_PROFILE,"option add *Radiobutton.font           -*-courier*-medium-r-*-*-14-*-*\n");
+  fprintf(HEAP_PROFILE,"option add *Radiobutton.relief         flat\n");
+  fprintf(HEAP_PROFILE,"option add *Radiobutton.borderWidth     2\n");
+  fprintf(HEAP_PROFILE,"option add *Radiobutton.highlightThickness 0\n");
+  fprintf(HEAP_PROFILE,"option add *Htext.font                 -*-times*-bold-r-*-*-14-*-*\n");
+  fprintf(HEAP_PROFILE,"option add *Htext.tileOffset           no\n");
+  fprintf(HEAP_PROFILE,"option add *header.font                        -*-times*-medium-r-*-*-14-*-*\n");
+  fprintf(HEAP_PROFILE,"option add *Barchart.font               -*-helvetica-bold-r-*-*-14-*-*\n");
+
+  fprintf(HEAP_PROFILE,"option add *Barchart.title             \"Heap profile of program ");
+  // TO DO: Add program name in here
+  fprintf(HEAP_PROFILE,"\"\n");
+
+  fprintf(HEAP_PROFILE,"option add *Axis.tickFont              -*-helvetica-medium-r-*-*-12-*-*\n");
+  fprintf(HEAP_PROFILE,"option add *Axis.titleFont             -*-helvetica-bold-r-*-*-12-*-*\n");
+  fprintf(HEAP_PROFILE,"option add *x.Command                  FormatXTicks\n");
+  fprintf(HEAP_PROFILE,"option add *x.Title                    \"Time (seconds)\"\n");
+  fprintf(HEAP_PROFILE,"option add *y.Title                    \"Heap usage (000 bytes)\"\n");
+  fprintf(HEAP_PROFILE,"option add *activeBar.Foreground       pink\noption add *activeBar.stipple             dot3\noption add *Element.Background            red\noption add *Element.Relief         raised\n");
+  fprintf(HEAP_PROFILE,"option add *Grid.dashes                        { 2 4 }\noption add *Grid.hide                  no\noption add *Grid.mapX                       \"\"\n");
+  fprintf(HEAP_PROFILE,"option add *Legend.Font                        \"-*-helvetica*-bold-r-*-*-12-*-*\"\noption add *Legend.activeBorderWidth       2\noption add *Legend.activeRelief              raised \noption add *Legend.anchor              ne \noption add *Legend.borderWidth             0\noption add *Legend.position          right\n");
+  fprintf(HEAP_PROFILE,"option add *TextMarker.Font            *Helvetica-Bold-R*14*\n");
+  fprintf(HEAP_PROFILE,"set visual [winfo screenvisual .] \nif { $visual != \"staticgray\" && $visual != \"grayscale\" } {\n    option add *print.background   yellow\n    option add *quit.background         red\n    option add *quit.activeBackground      red2\n}\n");
+  fprintf(HEAP_PROFILE,"htext .title -text {\n    Heap profile\n}\n");
+  fprintf(HEAP_PROFILE,"htext .header -text {\n    \%%\% \n");
+  fprintf(HEAP_PROFILE,"      radiobutton .header.stacked -text stacked -variable barMode \\\n            -anchor w -value \"stacked\" -selectcolor red -command {\n            .graph configure -barmode $barMode\n        } \n        .header append .header.stacked -width 1.5i -anchor w\n");
+  fprintf(HEAP_PROFILE,"    \%%\%      Heap usage stacked: overall height is the sum of the heap used. \n    \%%\% \n");
+  fprintf(HEAP_PROFILE,"        radiobutton .header.aligned -text aligned -variable barMode \\\n          -anchor w -value \"aligned\" -selectcolor yellow -command {\n            .graph configure -barmode $barMode        }\n        .header append .header.aligned -width 1.5i -fill x\n");
+  fprintf(HEAP_PROFILE,"    \%%\%      Heap usage components displayed side-by-side.\n    \%%\%\n");
+  fprintf(HEAP_PROFILE,"        radiobutton .header.overlap -text \"overlap\" -variable barMode \\\n            -anchor w -value \"overlap\" -selectcolor green -command {\n            .graph configure -barmode $barMode\n        }\n         .header append .header.overlap -width 1.5i -fill x\n");
+  fprintf(HEAP_PROFILE,"    \%%\%      Heap  usage shown as an overlapped histogram.\n    \%%\%\n");
+  fprintf(HEAP_PROFILE,"        radiobutton .header.normal -text \"normal\" -variable barMode \\\n            -anchor w -value \"normal\" -selectcolor blue -command {\n            .graph configure -barmode $barMode\n        }\n         .header append .header.normal -width 1.5i -fill x\n");
+  fprintf(HEAP_PROFILE,"    \%%\%      Heap components overlayed one on top of the next. \n}\n");
+  fprintf(HEAP_PROFILE,"htext .footer -text { To create a postscript file \"heap_profile.ps\", press the \%%\%\n  button $htext(widget).print -text print -command {\n        puts stderr [time {.graph postscript output heap_profile.ps}]\n  }\n  $htext(widget) append $htext(widget).print\n\%%\% button.}\n");
+  fprintf(HEAP_PROFILE,"barchart .graph -tile bgTexture\n");
+
+  // This is where the actual data comes in
+
+  fprintf(HEAP_PROFILE,"vector X ");
+  names_of_heap_objects(HEAP_PROFILE,ho_m);
+  fprintf(HEAP_PROFILE,"\nX set { ");
+  PrintXaxis(HEAP_PROFILE,th);
+  fprintf(HEAP_PROFILE," }\n");
+
+  print_heap_object_matrix(HEAP_PROFILE,th, ho_m);
+
+  // NAMES FOR THE ATTRIBUTES 
+  fprintf(HEAP_PROFILE,"set attributes {\n");
+  names_and_colour_assignment(HEAP_PROFILE,ho_m);
+  fprintf(HEAP_PROFILE,"}\n");
+  
+  fprintf(HEAP_PROFILE,"foreach {label yData color stipple} $attributes {\n    .graph element create $yData -label $label -bd 1 \\\n   -ydata $yData -xdata X -fg ${color}3 -bg ${color}1 -stipple $stipple\n}\n");
+  fprintf(HEAP_PROFILE,".header.stacked invoke\n");
+  fprintf(HEAP_PROFILE,"scrollbar .xbar -command { .graph axis view x } -orient horizontal\nscrollbar .ybar -command { .graph axis view y } -orient vertical\n.graph axis configure x -scrollcommand { .xbar set } -logscale no -loose no\n.graph axis configure y -scrollcommand { .ybar set } -logscale no -loose no\n");
+  fprintf(HEAP_PROFILE,"table . \\\n    0,0 .title -fill x \\\n    1,0 .header -fill x  \\\n    2,0 .graph -fill both \\\n    3,0 .xbar -fill x \\\n    5,0 .footer -fill x\n");
+  fprintf(HEAP_PROFILE,"table configure . r0 r1 r3 r4 r5 -resize none\n");
+  fprintf(HEAP_PROFILE,"Blt_ZoomStack .graph\nBlt_Crosshairs .graph\nBlt_ActiveLegend .graph\nBlt_ClosestPoint .graph\n");
+  fprintf(HEAP_PROFILE,".graph marker bind all <B2-Motion> {\n    set coords [\%W invtransform \%%x \%y]\n    catch { \%W marker configure [\%W marker get current] -coords $coords }\n}\n.graph marker bind all <Enter> {\n    set marker [\%W marker get current]\n    catch { %W marker configure $marker -bg green}\n}\n.graph marker bind all <Leave> {\n    set marker [\%W marker get current]\n    catch { %W marker configure $marker -bg \"\"}\n}\n");
+
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Read and create the raw profile data structure
+ * -------------------------------------------------------------------------- */
+
+/* void readRawProfile(FILE *fptr,int *nonodes) { */
+
+void readRawProfile(FILE *fp,int *nonodes, int MaxNoNodes) {
+  char    line[MAX_PROFILE_LINE_LENGTH];
+  char    stack[MAX_PROFILE_LINE_LENGTH];
+  char    rest[MAX_PROFILE_LINE_LENGTH];
+  int     i,nolines,sstepline,syncs;
+  char   *ptr,*drag;
+
+  float   comp_max,      comp_avg,      comp_min,          /* SYNCS    */
+          comm_max,      comm_avg,      comm_min,          /* COMP     */
+          comp_idle_max, comp_idle_avg, comp_idle_min;     /* COMM     */
+
+  /* Cost  relationships are comp=scc, comm=ticks, comp_idle=bytes */
+
+  long int hmax,havg,hmin;                                 /* COMPIDLE */
+
+  /* set to zero for now. Might use these later for heap costs. */
+
+  int     *result; /* Something to do with daVinci? */
+
+  /* GHC specific variables */
+
+  int a,b,c,d,x,y,z,count, next, throw;
+  int newloop;
+  char *ignore;
+  char e[MAX_STRING_SIZE];
+  char f[MAX_STRING_SIZE];
+  char g[MAX_STRING_SIZE];
+  char lline[MAX_PROFILE_LINE_LENGTH];
+
+  /* identifiers generated by the XML handler */
+  char *ccentre=">>cost_centre";
+  char *ccstack=">>cost_centre_stack";
+  char *sccsample=">>scc_sample";
+  char *heapsample=">>heap_sample";
+  char *heapupdate=">>heap_update";
+  char *heapobject=">>heap_object";
+  char *typeconstr=">>type_constr";
+  char *ending=">>";
+
+  char *blank="blank";
+  /* FILE *fp; */
+
+  cc_matrix *cc_m;
+  ccs_matrix *ccs_m;
+  heap_object_matrix *ho_m;
+  type_constr_matrix *tc_m;
+  TheHeap *th;
+
+  FILE *HEAP_PROFILE;
+
+  HEAP_PROFILE = fopen("GHCbarchart.tcl", "w");
+  if (HEAP_PROFILE == NULL){
+   fprintf(stderr,"tcl script generator: ERROR- GHCbarchart.tcl cannot be created\a\n");
+    exit(1);
+  }
+
+  th = (p_TheHeap) malloc (sizeof(TheHeap));
+  cc_m = (p_cc_matrix) malloc (sizeof(cc_matrix));
+  //cc_m = (p_cc_matrix) calloc(MAX_IDENTIFIERS,sizeof(_cc_));
+  ccs_m = (p_ccs_matrix) malloc (sizeof(ccs_matrix));
+  ho_m  = (p_heap_object_matrix) malloc (sizeof(heap_object_matrix));
+  tc_m  = (p_type_constr_matrix) malloc (sizeof(type_constr_matrix));
+
+  /* End of GHC specific variables */
+
+  //fprintf(log,"Number 1 %i \n",MAX_IDENTIFIERS*sizeof(_cc_));
+  //fprintf(log,"Number 2 %i \n",sizeof(cc_matrix));
+
+  nolines=0; /* Number of lines read in from profile log file */
+
+  /* GHC specific */
+  count = 0;
+  next = 0;
+
+  initialise_cc_matrix(cc_m);
+  initialise_ccs_matrix(ccs_m);
+  initialise_heap_object_matrix(ho_m);
+  initialise_type_constr_matrix(tc_m);
+  initialise_TheHeap(th);
+
+  fprintf(log,"MAX_IDENTIFIERS = %i \n",MAX_IDENTIFIERS);
+  
+  /* end GHC specific */
+
+  /* CAF fixing */
+  fill_cc_matrix(cc_m,"CAF:REPOSITORY","PROFILER","PROFILER",MAX_IDENTIFIERS-1);
+  fill_ccs_matrix(ccs_m,MAX_IDENTIFIERS-1,1,0.0,0.0,0.0,0,-1,MAX_IDENTIFIERS-1);
+
+  /* 
+
+  This builds a node in the graph called CAF:REPOSITORY, which can be 
+  found off the root node. All CAFs are subsequently hung from this node
+  which means the node node can be hidden using the abstraction 
+  mechanisms provided by daVinci.
+
+  */
+
+
+  /* This is the GHC file handler which reads the lines from the profile log file and */
+  /* puts the stack and cost information in the raw profile data structure */
+
+   while (fscanf(fp,"%s",lline))
+   { 
+    /* Kill the end of the logfile with the ">>" string */
+    if (strcmp(lline,ending)==0) break;
+
+    /* Deal with the cost centres */
+    if (strcmp(ccentre,lline)==0)
+    {
+      next = fgetc(fp);
+      //while (fscanf(fp," %i %[^ ] %[^ ] %s", &z, e, f, g)!=0)
+      while (fscanf(fp," %i %[^ ] %s", &z, e, f)!=0)
+      {
+        fprintf(log,"Declaring cost centre `%i %s %s %s' \n",z,e,f,f);
+        fflush(log);
+        fill_cc_matrix(cc_m,e,f,f,z);
+        next = fgetc(fp);
+      }
+    }
+    else 
+    {
+
+      /* Deal with the cost centre stacks */
+      if (strcmp(ccstack,lline)==0)
+      { 
+        next = fgetc(fp);
+        while (fscanf(fp,"%i %i %i",&a,&d,&b)!=0)
+        {
+          if (d==1) /* of size one */
+          {  
+            fprintf(log,"Declaring cost centre stack `%i %i %i'\n",a,d,b);
+            fill_ccs_matrix(ccs_m,b,-1,(*ccs_m)[a].scc,(*ccs_m)[a].ticks,(*ccs_m)[a].bytes,0,-1,a);
+          }
+          if (d==2) /* of size > 1 */
+          { 
+            fscanf(fp," %i",&c);
+
+            /* CAF fixing */
+            fprintf(log,"Declaring cost centre stack `%i %i %i %i'\n",a,d,b,c);
+            if ((c==1)&&!(strncmp((*cc_m)[b].name,"CAF",2)))
+               // fill_ccs_matrix(ccs_m,b,MAX_IDENTIFIERS-1,(*ccs_m)[a].scc,(*ccs_m)[a].ticks,(*ccs_m)[a].bytes,0,-1,a);
+               /* The line above hangs all CAFs off the CAF:REPOSITORY node
+                  in the daVinci graph. For programs which have a small 
+                  number of CAFs this works nicely. However, when the 
+                  number of CAFs become very large (eg +200) then the 
+                  daVinci graph begins to look horid and, after (say)
+                  +500 CAF nodes, becomes very slow to load. So to 
+                  fix this we replace the code with the line below.
+               */
+                 if (!(strncmp((*cc_m)[b].name,"CAF:main",7)))
+                    /* Treat CAF:main as a normal node */ 
+                    fill_ccs_matrix(ccs_m,b,c,(*ccs_m)[a].scc,(*ccs_m)[a].ticks,(*ccs_m)[a].bytes,0,-1,a); 
+                    /* merge the rest */
+                 else
+                    //add_ccs_costs(ccs_m,0,MAX_IDENTIFIERS-1,(*ccs_m)[a].scc,(*ccs_m)[a].ticks,(*ccs_m)[a].bytes,0,0);
+                    fill_ccs_matrix(ccs_m,MAX_IDENTIFIERS-1,1,(*ccs_m)[a].scc,(*ccs_m)[a].ticks,(*ccs_m)[a].bytes,0,-1,a);
+                /* This does not even bother registering the new CAFs
+                   as daVinci nodes, but instead just merges the CAF
+                   with the CAF:REPOSITORY node. This greatly reduces
+                   the number of CAFs daVinci has to deal with, though
+                   may make the graph look a little different!
+
+                   Also note that now Simon has changed the semantics,
+                   you will want to treat adding CAF nodes in a 
+                   different way to adding normal program nodes
+                 */
+            else 
+               /* Normal mode */
+               fill_ccs_matrix(ccs_m,b,c,(*ccs_m)[a].scc,(*ccs_m)[a].ticks,(*ccs_m)[a].bytes,0,-1,a);
+          }
+          next = fgetc(fp);
+        }
+      } 
+      else
+      {
+
+        /* Deal with the scc_samples */
+        if (strcmp(sccsample,lline)==0)
+        {
+          next = fgetc(fp);
+          while (fscanf(fp,"%i %i %i %i",&a,&d,&b,&c))
+          {
+            fprintf(log,"Loading scc_samples `%i %i %i %i'\n",a,d,b,c);
+            add_ccs_costs(ccs_m,0,a,d,b,c,0,0);
+            next = fgetc(fp);
+          }
+        } /* end sccsample if */
+        else 
+        {
+        
+          /* Deal with the heap samples */
+          if (strcmp(heapsample,lline)==0)
+          {
+            next = fgetc(fp);
+            while (fscanf(fp,"%i %i %i",&a,&d,&b))
+            {
+              fprintf(log,"Loading heap_samples `%i %i %i'\n",a,d,b);
+              add_heap_sample_costs(ccs_m,0,a,0,0,0,d,b);
+              next = fgetc(fp);
+            }
+          } /* end heapsample if */
+          else 
+          {
+
+            /* Deal with the heap objects */
+            if (strcmp(heapobject,lline)==0)
+            {
+              next = fgetc(fp);
+              while (fscanf(fp,"%i %i",&a,&d)) 
+              {
+                if (d==1) 
+                {
+                  fscanf(fp," %s %i",e,&b);
+                  add_heap_object(ho_m,a,d,e,b);
+                }
+                else 
+                {
+                  fscanf(fp," %s",e);
+                  add_heap_object(ho_m,a,d,e,-1);
+                }
+                next = fgetc(fp);
+              }
+            } /* end heapobject if */
+            else
+            {
+
+              /* Deal with the type constructors */ 
+              if (strcmp(typeconstr,lline)==0)
+              {
+                next = fgetc(fp);
+                while (fscanf(fp,"%i %s %s",&a,e,f))
+                {
+                  add_type_constr_object(tc_m,a,e,f);
+                  next = fgetc(fp);
+                }
+              } /* end type constructor if */
+              else
+              {
+                
+                /* Deal with the heap_updates */ 
+                if (strcmp(heapupdate,lline)==0)
+                {
+                  next = fgetc(fp);
+                  while (fscanf(fp,"%i %i %i %i %i %i",&a,&d,&b,&c,&z,&x))
+                  {
+                    add_to_TheHeap(th,a,b,c,z);
+                    fprintf(log,"Adding heap sample %i %i %i %i\n",a,b,c,z);
+                    while (x) /* more than one sample */
+                    {
+                      fscanf(fp," %i %i %i %i",&b,&c,&z,&x);
+                      add_to_TheHeap(th,a,b,c,z);
+                      fprintf(log,"Adding heap sample %i %i %i %i\n",a,b,c,z);
+                    }  
+                    next = fgetc(fp);
+                  }
+
+                } /* end heap update if */
+
+              }  /* end type constructor else */
+
+             } /* end heapobject else */
+
+           } /* end heapsample else */
+         } /* end sccsample else */
+       } /* end ccstack else */
+     } /* end ccstack if */
+   } /* end while */
+
+   print_cc_matrix(cc_m);
+   print_ccs_matrix(ccs_m);
+   fprintf(log,"There are %i stacks\n",CountStacks(ccs_m));
+   print_type_constr_matrix(tc_m);
+
+   /* Functions for heap profile */
+   print_TheHeap(th);
+   fprintf(log,"The units for the x axis are \n");
+   PrintXaxis(log,th);
+   fprintf(log,"\n");
+   fprintf(log,"There are %i distinct heap objects\n",number_of_heap_objects(ho_m));
+   names_of_heap_objects(log,ho_m);
+   names_and_colour_assignment(log,ho_m);
+   print_heap_object_matrix(log,th,ho_m);
+
+   PrintAllStacks(ccs_m,cc_m);
+   /* comment out line below to remove the heap profile generator */
+   produce_HEAP_PROFILE(HEAP_PROFILE,th,ho_m);
+   fclose(HEAP_PROFILE);
+
+   /* End of GHC file handler */
+  
+
+  /* Now process the stack matrix */ 
+
+  for (newloop=0;newloop<MAX_IDENTIFIERS;newloop++) 
+  { if ((*ccs_m)[newloop].cc != 0)
+    {
+         
+    sstepline = 0;
+    FormStack2(ccs_m,cc_m,newloop,stack);
+
+    syncs = 0;     
+    comp_max = (float)(*ccs_m)[newloop].scc; 
+    comp_avg = (float)(*ccs_m)[newloop].scc; 
+    comp_min = (float)(*ccs_m)[newloop].scc; 
+    comm_max = (float)(*ccs_m)[newloop].ticks; 
+    comm_avg = (float)(*ccs_m)[newloop].ticks; 
+    comm_min = (float)(*ccs_m)[newloop].ticks; 
+    comp_idle_max = (float)(*ccs_m)[newloop].bytes; 
+    comp_idle_avg = (float)(*ccs_m)[newloop].bytes; 
+    comp_idle_min = (float)(*ccs_m)[newloop].bytes; 
+    hmax = 0.0; havg = 0.0; hmin = 0.0; 
+
+      /* Dynamic memory allocation for raw_profile data structure */ 
+
+      if (raw_profile_next==raw_profile_size) enlargeRawProfile();
+
+      /* Assign data from single logfile entry to raw_profile data structure */
+      /* this deals with the cost metrics */
+
+      raw_profile[raw_profile_next].active            = 1;
+      raw_profile[raw_profile_next].cost.syncs        = syncs;
+      raw_profile[raw_profile_next].cost.comp_max     = comp_max;
+      raw_profile[raw_profile_next].cost.comp_avg     = comp_avg;
+      raw_profile[raw_profile_next].cost.comp_min     = comp_min;
+      raw_profile[raw_profile_next].cost.comm_max     = comm_max;
+      raw_profile[raw_profile_next].cost.comm_avg     = comm_avg;
+      raw_profile[raw_profile_next].cost.comm_min     = comm_min;
+      raw_profile[raw_profile_next].cost.comp_idle_max= comp_idle_max;
+      raw_profile[raw_profile_next].cost.comp_idle_avg= comp_idle_avg;
+      raw_profile[raw_profile_next].cost.comp_idle_min= comp_idle_min;
+      raw_profile[raw_profile_next].cost.hrel_max     = hmax;
+      raw_profile[raw_profile_next].cost.hrel_avg     = havg;
+      raw_profile[raw_profile_next].cost.hrel_min     = hmin;
+
+      /* this deals with the stack itself */
+
+      raw_profile[raw_profile_next].stack=calloc(MAX_STACK_DEPTH,
+                                                sizeof(int));
+      if (raw_profile[raw_profile_next].stack==NULL) {
+        fprintf(stderr,"{readRawProfile} unable to allocate stack entry");
+        exit(1);
+      }
+
+      fprintf(log,"STACK=\"%s\"\n",stack);
+      raw_profile[raw_profile_next].stack_size=1;
+      /* move the stack read frame to the first space (or comma) in the stack string */ 
+      for(ptr=stack; ((*ptr)!=' ') && (*ptr!=',');ptr++) {}
+      fprintf(log,"TOS=%d at line %d\n",*ptr,sstepline);
+     
+      /* to distinguish the head of the stack from the rest */
+      /* if read frame points to space you are at the head of the stack */
+      if (*ptr==' ') 
+        /* raw_profile[raw_profile_next].stack[0]
+          =lookupSymbolTable(CG_SSTEP,sstepline,(*ptr='\0',stack)); */
+        /* This line has changed as GHC treats its cost-centres in a different     */
+        /* way to BSP. There is no distinction between 'a cost centre at line x'   */
+        /* and a normal cost centre. The fix is easy, just treat all cost centres, */
+        /* even those at the head of the stack in the same way.                    */
+           raw_profile[raw_profile_next].stack[0]
+          =lookupSymbolTable(CG_STACK,sstepline,(*ptr='\0',stack));
+      else
+      /* otherwise you are looking at just another stack element */
+        raw_profile[raw_profile_next].stack[0]
+          =lookupSymbolTable(CG_STACK,sstepline,(*ptr='\0',stack));
+
+      ptr++; /* move the read frame on one */
+      drag=ptr;
+      for(;*ptr;ptr++) { /* find the next element in the stack */
+        if (*ptr==',') {
+         *ptr='\0';
+          if (Verbose) fprintf(log,"NAME=\"%s\"\n",drag); /* name of the next element */
+          if (!ignore_function(drag)) {
+            raw_profile[raw_profile_next].stack[
+              raw_profile[raw_profile_next].stack_size++]
+              = lookupSymbolTable(CG_STACK,0,drag); /* add element to the raw_profile */
+         }
+          drag = ptr+1;
+        }
+      }
+
+      /* create cost object */
+
+      raw_profile[raw_profile_next].cost.proc
+       =calloc(bsp_p,sizeof(object_cost_proc));
+      if (raw_profile[raw_profile_next].cost.proc==NULL) {
+       fprintf(stderr,"Unable to allocate storage");
+       exit(0);
+      }
+  
+      /* process the HREL information - one set for every BSP process */
+
+      for(i=0;i<bsp_p;i++) {
+
+         raw_profile[raw_profile_next].cost.proc[i].proc_comp     = 0.0; 
+         raw_profile[raw_profile_next].cost.proc[i].proc_comm     = 0.0; 
+         raw_profile[raw_profile_next].cost.proc[i].proc_comp_idle= 0.0; 
+         raw_profile[raw_profile_next].cost.proc[i].proc_hrel_in  = 0; 
+         raw_profile[raw_profile_next].cost.proc[i].proc_hrel_out = 0; 
+
+      }
+
+      raw_profile_next++;    /* Increase the raw profile data structure counter */
+      nolines++;             /* Increase the number of lines read               */
+
+       strcpy(stack,""); /* reset the stack */
+    } /* end of new if statement */
+  } /* end of new for loop */
+
+  *nonodes = symbol_table_next;
+  fprintf(log,"%s: read %d lines from profile.Graph contains %i nodes. 
+          \n",Pgm,nolines,symbol_table_next);
+
+  free_cc_matrix(cc_m); /* be nice and clean up the cost centre matrix */
+}
+
+/* -----------------------------------------------------------------------------
+ * Pretty print the raw profile data
+ * -------------------------------------------------------------------------- */
+
+void printRawProfile() {
+  int i,j;
+  object_cost *cost;
+  int         *stack;
+  
+  fprintf(log,"\n\nRAW DATA:\n");
+  for(i=0;i<raw_profile_next;i++) {
+    cost  = &raw_profile[i].cost;
+    stack = raw_profile[i].stack;
+    fprintf(log,"Stack=[");
+    for(j=0;j<raw_profile[i].stack_size;j++) 
+      printSymbolTable_entry(stack[j]);
+    fprintf(log,"] %d Syncs %f Comp %f Comm %f Wait\n\n",
+           cost->syncs,cost->comp_max,cost->comm_max,cost->comp_idle_max);
+  }
+}
+
+/* -----------------------------------------------------------------------------
+ * Create connectivity matrix
+ * -------------------------------------------------------------------------- */
+
+void createConnectivityMatrix(int NoNodes,Matrix *graph,
+                             Matrix *costs,int *root, int inherit) {
+  object_cost zero_cost,*update;
+  int i,j,this,next;
+
+
+  zero_cost.comp_max     =0.0;
+  zero_cost.comp_avg     =0.0;
+  zero_cost.comp_min     =0.0;
+  zero_cost.comm_max     =0.0;
+  zero_cost.comm_avg     =0.0;
+  zero_cost.comm_min     =0.0;
+  zero_cost.comp_idle_max=0.0;
+  zero_cost.comp_idle_avg=0.0;
+  zero_cost.comp_idle_min=0.0;
+  zero_cost.hrel_max     =0;
+  zero_cost.hrel_avg     =0;
+  zero_cost.hrel_min     =0;
+  zero_cost.syncs=0;
+  zero_cost.proc = NULL;
+  *graph = newMat(NoNodes,NoNodes,sizeof(int),(i=0,&i));
+  *costs = newMat(NoNodes,1,sizeof(object_cost),&zero_cost);
+  for(i=0;i<NoNodes;i++) {
+    update=&Mat(object_cost,*costs,i,0);
+    update->proc=calloc(bsp_p,sizeof(object_cost_proc));
+    if (update->proc==NULL){
+      fprintf(stderr,"Unable to allocate storage");
+      exit(0);
+    }
+    for(j=0;j<bsp_p;j++) {
+      update->proc[j].proc_comp      =0.0;
+      update->proc[j].proc_comm      =0.0;
+      update->proc[j].proc_comp_idle =0.0;
+      update->proc[j].proc_hrel_in   =0;
+      update->proc[j].proc_hrel_out  =0;
+    }
+  }
+      
+  for(i=0;i<raw_profile_next;i++) {
+    if (raw_profile[i].active) {
+      this = raw_profile[i].stack[0];
+      next = this;
+      Mat(int,*graph,this,next) = 1;
+      update = &Mat(object_cost,*costs,next,0);
+      add_costs(update,raw_profile[i].cost);
+      for(j=1;j<raw_profile[i].stack_size;j++) {
+        this = next;
+        next = raw_profile[i].stack[j];
+        Mat(int,*graph,next,this)=1;
+       update = &Mat(object_cost,*costs,next,0);
+        /* include this line for INHERITANCE; remove it for not! */
+        if (inherit) add_costs(update,raw_profile[i].cost);
+      }
+    }
+  }
+  *root =  raw_profile[0].stack[raw_profile[0].stack_size-1];
+
+  /* Check graph isn't empty */
+  if (!Mat_dense(*costs,*root,0)) *root=-1;
+}
+
+void printConnectivityMatrix(Matrix graph,Matrix costs,int root) { 
+  int i,j;
+  object_cost cost;
+
+  fprintf(log,"Root node is %d\n",root);
+  for(i=0;i<graph.rows;i++) {
+    fprintf(log,"%4d)",i);
+    printSymbolTable_entry(i);
+    cost = Mat(object_cost,costs,i,0);
+    fprintf(log,"%d %f %f %f\n\tBranch=[",
+           cost.syncs,cost.comp_max,cost.comm_max,cost.comp_idle_max);
+    for(j=0;j<graph.cols;j++) 
+      if (Mat_dense(graph,i,j)) fprintf(log,"%d ",j);
+    fprintf(log,"]\n\n");
+  }
+}
diff --git a/ghc/utils/prof/cgprof/cgprof.h b/ghc/utils/prof/cgprof/cgprof.h
new file mode 100644 (file)
index 0000000..84cbb54
--- /dev/null
@@ -0,0 +1,82 @@
+/* ------------------------------------------------------------------------
+ * $Id: cgprof.h,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+ *                                                                     
+ *     Copyright (C) 1995-2000 University of Oxford
+ *                                                                     
+ * Permission to use, copy, modify, and distribute this software,
+ * and to incorporate it, in whole or in part, into other software,
+ * is hereby granted without fee, provided that
+ *   (1) the above copyright notice and this permission notice appear in
+ *      all copies of the source code, and the above copyright notice
+ *      appear in clearly visible form on all supporting documentation
+ *      and distribution media;
+ *   (2) modified versions of this software be accompanied by a complete
+ *      change history describing author, date, and modifications made;
+ *      and
+ *   (3) any redistribution of the software, in original or modified
+ *      form, be without fee and subject to these same conditions.
+ * --------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include "symbol.h"
+#include "matrix.h"
+
+/* -----------------------------------------------------------------------------
+ * Data structures associated with parsed data
+ * -------------------------------------------------------------------------- */
+
+/* -----------------------------------------------------------------------------
+ * Cost attributes
+ * -------------------------------------------------------------------------- */
+
+#ifndef _CGPROF_H_
+#define _CGPROF_H_
+
+typedef struct {
+  double   proc_comp;
+  double   proc_comm;
+  double   proc_comp_idle;
+  long int proc_hrel_in;
+  long int proc_hrel_out;
+} object_cost_proc;
+
+typedef struct {
+  double   comp_max,      comp_avg,      comp_min;
+  double   comm_max,      comm_avg,      comm_min;
+  double   comp_idle_max, comp_idle_avg, comp_idle_min;
+  long int hrel_max,      hrel_avg,      hrel_min;
+  object_cost_proc *proc;
+  int    syncs;
+} object_cost;
+
+/* -----------------------------------------------------------------------------
+ * Sequence of cost centres
+ * -------------------------------------------------------------------------- */
+
+typedef struct {
+  object_cost  cost;
+  name_id     *stack;
+  int          stack_size;
+  int          active;
+} parsed_cost_object;
+
+#define RAW_PROFILE_INIT_SIZE 100
+extern int                 raw_profile_next;
+extern int                 raw_profile_size;
+extern parsed_cost_object *raw_profile;
+
+/* -----------------------------------------------------------------------------
+ * Misc.
+ * -------------------------------------------------------------------------- */
+
+extern int   Verbose;
+extern char *Pgm;
+extern void readRawProfile(FILE *,int*,int);
+extern void printRawProfile();
+extern void add_costs(object_cost *,object_cost);
+extern void createConnectivityMatrix(int,Matrix *,Matrix *,int *,int);
+extern void printConnectivityMatrix(Matrix,Matrix,int);
+extern FILE* log;
+#endif
diff --git a/ghc/utils/prof/cgprof/daVinci.c b/ghc/utils/prof/cgprof/daVinci.c
new file mode 100644 (file)
index 0000000..667a270
--- /dev/null
@@ -0,0 +1,765 @@
+/* ------------------------------------------------------------------------
+ * $Id: daVinci.c,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+ *                                                                     
+ *     Copyright (C) 1995-2000 University of Oxford
+ *                                                                     
+ * Permission to use, copy, modify, and distribute this software,
+ * and to incorporate it, in whole or in part, into other software,
+ * is hereby granted without fee, provided that
+ *   (1) the above copyright notice and this permission notice appear in
+ *      all copies of the source code, and the above copyright notice
+ *      appear in clearly visible form on all supporting documentation
+ *      and distribution media;
+ *   (2) modified versions of this software be accompanied by a complete
+ *      change history describing author, date, and modifications made;
+ *      and
+ *   (3) any redistribution of the software, in original or modified
+ *      form, be without fee and subject to these same conditions.
+ * --------------------------------------------------------------------- */
+
+#include "daVinci.h"
+#include <stdarg.h>
+#include <string.h>
+
+static char* extra_space(int);
+static void recur_graphToDaVinci(int,Matrix *, Matrix *,char*,int);
+static char *parse_word(char**);
+static char *parse_quoted(char**);
+static char *dup_str(char*);
+double this_total_time,
+       this_total_comp_max, this_total_comp_avg,
+       this_total_comm_max, this_total_comm_avg, 
+       this_total_comp_idle_max, this_total_comp_idle_avg;
+long int this_hrel_max, this_hrel_avg;
+int  this_syncs;
+
+char *lastDavinciCmd;
+
+/* -----------------------------------------------------------------------------
+ * Send a command with ok return value daVinci
+ * -------------------------------------------------------------------------- */
+
+void cmdDaVinci(char* format,...) {
+  static char xs[MAX_PROFILE_LINE_LENGTH];
+  va_list args;
+
+  va_start(args, format);
+  vfprintf(stdout, format, args);
+  fprintf(stdout, "\n");
+  va_end(args);
+  fflush(stdout); 
+  lastDavinciCmd = format;
+}
+
+/* -----------------------------------------------------------------------------
+ * Initialise daVinci
+ * -------------------------------------------------------------------------- */
+
+void initDaVinci() {
+  cmdDaVinci("window(title(\"GHC profiler: cost-centre-stack view\"))\n");
+  cmdDaVinci("set(font_size(8))");  
+  cmdDaVinci("set(animation_speed(0))");
+  cmdDaVinci("set(scrolling_on_selection(false))");
+  /* SAJ */
+  /* cmdDaVinci("set(no_cache(true)))"); */
+  cmdDaVinci("app_menu(create_icons(["
+                  "icon_entry(\"delete\","
+                             "\"delete.xbm\","
+                             "\"Delete node and its children\"),"
+                  "icon_entry(\"undo\","
+                             "\"undo.xbm\","
+                             "\"Undo delete\"),"
+                  "blank,"
+                  "icon_entry(\"time\","
+                             "\"time.xbm\","
+                             "\"Cost metric view\"),"
+                  "icon_entry(\"percent\","
+                             "\"percent.xbm\","
+                             "\"Percentage view\"),"
+                  "blank,"
+                  "icon_entry(\"compress\","
+                             "\"compress.xbm\","
+                             "\"Compressed node view\"),"
+                  "icon_entry(\"uncompress\","
+                             "\"uncompress.xbm\","
+                             "\"Uncompressed node view\"),"
+                  "blank,"
+                  "icon_entry(\"absolute\","
+                             "\"absolute.xbm\","
+                             "\"Display inherited profile results\"),"
+                  "icon_entry(\"absdelta\","
+                             "\"absdelta.xbm\","
+                             "\"Display flat profile results\"),"
+                  "icon_entry(\"reldelta\","
+                             "\"reldelta.xbm\","
+                             "\"Trim zero-cost sub-trees\"),"
+                  "icon_entry(\"weightdelta\","
+                             "\"weightdelta.xbm\","
+                             "\"Trim zero-cost nodes\"),"
+                  "blank,"
+                 "icon_entry(\"sync\","
+                             "\"sync.xbm\","
+                             "\"Graph view\"),"
+                  "icon_entry(\"comp\","
+                             "\"comp.xbm\","
+                             "\"SCCs critical path\"),"
+                  "icon_entry(\"comm\","
+                             "\"comm.xbm\","
+                             "\"Computation time critical path\"),"
+                  "icon_entry(\"wait\","
+                             "\"wait.xbm\","
+                             "\"Heap usage critical path\"),"
+                  "icon_entry(\"hrel\","
+                             "\"hrel.xbm\","
+                             "\"Node spy\"),"
+                  "blank,"
+                 "icon_entry(\"help\","
+                             "\"help.xbm\","
+                             "\"Help\"),"
+              "]))");
+
+  activateDaVinciMenu("default");     
+  cmdDaVinci("app_menu(create_menus([menu_entry_mne(\"jump\",\"Goto a node\",\"G\",control,\"G\")]))\n");
+  /* SAJ */
+  // cmdDaVinci("app_menu(activate_menus([\"jump\"]))"); 
+}
+
+/* -----------------------------------------------------------------------------
+ * Menu FSM
+ * -------------------------------------------------------------------------- */
+
+void activateDaVinciMenu(char *pressed) {
+  static int compress=1,time=1,critical_type=0,critical=0,undo=1,delete=0;
+
+  if (strcmp(pressed,"absolute")==0)    critical_type=0;
+  if (strcmp(pressed,"absdelta")==0)    critical_type=1;
+  if (strcmp(pressed,"reldelta")==0)    critical_type=2;
+  if (strcmp(pressed,"weightdelta")==0) critical_type=3;
+
+  if (strcmp(pressed,"sync")==0)  critical=0;
+  if (strcmp(pressed,"comp")==0)  critical=1;
+  if (strcmp(pressed,"comm")==0)  critical=2;
+  if (strcmp(pressed,"wait")==0)  critical=3;
+  if (strcmp(pressed,"hrel")==0)  critical=4;
+
+  if (strcmp(pressed,"compress")==0 || strcmp(pressed,"uncompress")==0) 
+    compress=!compress;
+
+  if (strcmp(pressed,"time")==0 || strcmp(pressed,"percent")==0)
+    time=!time;
+
+  if (strcmp(pressed,"undo")==0)   {undo=!undo;}
+  if (strcmp(pressed,"delete")==0) {delete=!delete;}
+
+  printf("app_menu(activate_icons([");
+  if (critical_type!=0) printf("\"absolute\",");
+  if (critical_type!=1) printf("\"absdelta\",");
+  if (critical_type!=2) printf("\"reldelta\",");
+  if (critical_type!=3) printf("\"weightdelta\",");
+
+  if (critical!=0) printf("\"sync\",");
+  if (critical!=1) printf("\"comp\",");
+  if (critical!=2) printf("\"comm\",");
+  if (critical!=3) printf("\"wait\",");
+  if (critical!=4) printf("\"hrel\",");
+
+  if (!compress)   printf("\"compress\",");
+  if (compress)    printf("\"uncompress\",");
+  if (!time)       printf("\"time\",");
+  if (time)        printf("\"percent\",");
+  if (!delete)     printf("\"delete\",");
+  if (!undo)       printf("\"undo\",");
+  
+  cmdDaVinci("\"help\"]))");  
+}
+
+/* -----------------------------------------------------------------------------
+ * Graph to daVinci
+ * -------------------------------------------------------------------------- */
+
+void graphToDaVinci(int root,Matrix *graph, Matrix *costs, int removezerocosts) {
+  int i,j;
+  object_cost *ptr;
+  char zeronodes[MAX_PROFILE_LINE_LENGTH*2];     // is this a sen. MAX
+  char TEMPzeronodes[MAX_PROFILE_LINE_LENGTH*2];
+  char* p_zeronodes = zeronodes;
+  char* TEMPp_zeronodes = TEMPzeronodes;
+  printf("graph(new([");
+  if (PrintLogo) {
+    /* I have implemented some name changes here. They are purely for output and */
+    /* following the relation (comp = scc, comm = ticks, wait = bytes            */
+    printf("l(\"info\",n(\"\",["
+          "a(\"COLOR\",\"gold\"),"
+          "a(\"FONTFAMILY\",\"courier\"),"
+          //"a(\"_GO\",\"icon\"),"
+          //"a(\"ICONFILE\",\"oxpara.xbm\"),"
+          "a(\"OBJECT\",\""
+           "Program statistics\\n\\n"
+          "Time elapsed     =  %6.2f ticks\\n"
+          "Heap usage       =  %6.2f bytes\\n"
+          "Total scc count  =  %6.2f (scc)\\n"
+          "\")],[])),",
+           TotalComm,TotalCompIdle,
+          TotalComp
+          );
+  } 
+
+  if (root==-1) {
+    printf("]))\n");
+  } else {
+    ptr = &Mat(object_cost,*costs,root,0);
+    this_total_comp_max     = ptr->comp_max;
+    this_total_comp_avg     = ptr->comp_avg;
+    this_total_comm_max     = ptr->comm_max;
+    this_total_comm_avg     = ptr->comm_avg;
+    this_total_comp_idle_max= ptr->comp_idle_max;
+    this_total_comp_idle_avg= ptr->comp_idle_avg;
+    this_total_time         = 0.00001 + 
+                              this_total_comp_max+ this_total_comm_max;
+    this_hrel_max       = ptr->hrel_max;
+    this_hrel_avg       = ptr->hrel_avg;
+    this_syncs          = ptr->syncs;
+    recur_graphToDaVinci(root,graph,costs,p_zeronodes,removezerocosts);
+
+    printf("]))\n");
+    fflush(stdout);
+    cmdDaVinci("special(focus_node(\"%d\"))\n",root);
+
+    /* graph will have been altered so that visted elements are marked
+       by a negative value. These are reset */
+    for(i=0;i<graph->rows;i++) {
+      for(j=0;j<graph->cols;j++) {
+        if (Mat_dense(*graph,i,j))
+          if (Mat(int,*graph,i,j)<0) Mat(int,*graph,i,j)=1;
+      }
+    }
+
+    if (removezerocosts==1)
+    {
+      if (strlen(p_zeronodes)>0) 
+         { strncpy(TEMPp_zeronodes,p_zeronodes,strlen(p_zeronodes)-1);
+           printf("select_nodes_labels([%s])\n",TEMPp_zeronodes);
+         }
+      strcpy(TEMPp_zeronodes,"");
+      strcpy(p_zeronodes,"");
+    }
+  }
+}
+
+static char *printCompressNode(int node, object_cost *ptr) {
+  char name[MAX_FUNNAME+20];
+  char comp[MAX_FUNNAME+20];
+  char comm[MAX_FUNNAME+20];
+  static char res[(MAX_FUNNAME+20)*4];
+  char tempstring[MAX_FUNNAME+20];
+  char *padding;
+  int width=0,x;
+  char delimiter[] = "&";
+
+  if (symbol_table[node].type==CG_SSTEP) 
+    sprintf(name,"%d %s",
+           symbol_table[node].lineno,symbol_table[node].filename);
+  else
+  { 
+    strcpy(tempstring,symbol_table[node].filename);
+    sprintf(name,"%s",strtok(tempstring,delimiter));
+  }  
+
+  if (NodeviewTime) {
+    /* changed this for GHC stats */
+    sprintf(comp,"\\nTime  %6.2fticks\\n",ptr->comm_max);
+    sprintf(comm,"Bytes %6.2funits",ptr->comp_idle_max);
+  } else {
+    sprintf(comp,"\\nTime  %6.2f%%\\n",(ptr->comm_max/TotalComm)*100.0);
+    sprintf(comm,"Bytes %6.2f%%",(ptr->comp_idle_max/TotalCompIdle)*100.0);
+  }
+  /* Slightly arbitrary choice for max display length of CC string */
+  /* If it is larger than this the display nodes look bad */
+  if (strlen(name)>20) name[20]='\0';
+  x=strlen(name);
+  if (((20-(strlen(name)+3))/2)>19)
+     padding = extra_space(0);
+  else
+     padding = extra_space((20-(strlen(name)+3))/2); /* includes \\n */
+  strcpy(res,padding);
+  strcat(res,name);
+  strcat(res,comp);
+  strcat(res,comm);
+  return res;
+}
+
+static char *printUncompressNode(int node, object_cost *ptr) {
+  char name   [MAX_FUNNAME+40];
+  char module [MAX_FUNNAME+40];
+  char group  [MAX_FUNNAME+40];
+  char syncs[MAX_FUNNAME+40];
+  char head [MAX_FUNNAME+40];
+  char comp [MAX_FUNNAME+40];
+  char comm [MAX_FUNNAME+40];
+  char wait [MAX_FUNNAME+40];
+  char hrel [MAX_FUNNAME+40];
+  char tempstring[MAX_FUNNAME+20];
+  char tempstring2[MAX_FUNNAME+20];
+  char *tempstring3;
+  char *tempstring5;
+  char tempstring4[MAX_FUNNAME+20];
+  char delimiter[] = "&";
+
+
+  static char res[(MAX_FUNNAME+40)*7];
+  char *padding;
+  int width=0,x;
+
+  if (symbol_table[node].type==CG_SSTEP) 
+    sprintf(name,"%s line %d\\n",
+           symbol_table[node].filename,symbol_table[node].lineno);
+  else
+  {
+    strcpy(tempstring,symbol_table[node].filename);
+    strcpy(tempstring2,symbol_table[node].filename);
+    sprintf(name,"%s",strtok(tempstring,delimiter));
+    strcpy(tempstring4,tempstring2);
+    tempstring5 = strpbrk(tempstring4,delimiter);
+    sprintf(module,"%s",strtok(tempstring5+1,delimiter));
+    tempstring3 = strrchr(tempstring2,'&');
+    sprintf(group,"%s",tempstring3+1);
+  }
+
+  sprintf(syncs,"");
+  if (NodeviewTime) {
+
+    sprintf(head, "Metric   Total  \\n");
+    sprintf(comp, " Time    %6.2ft \\n",ptr->comm_max);
+    sprintf(comm, " Bytes   %6.2fu \\n",ptr->comp_idle_max);
+    sprintf(wait, " SCC     %6.2fc \\n",ptr->comp_max);
+
+
+  } else {
+
+    sprintf(head, "Metric   Total  \\n");
+    sprintf(comp, " Time    %5.1f%% \\n",100.0*SAFEDIV(ptr->comm_max,TotalComm));
+    sprintf(comm, " Bytes   %5.1f%% \\n",100.0*SAFEDIV(ptr->comp_idle_max,TotalCompIdle));
+    sprintf(wait, " SCC     %5.1f%% \\n",100.0*SAFEDIV(ptr->comp_max,TotalComp));
+
+  }
+         
+  if ((x=strlen(name))>width)  width=x;
+  if ((x=strlen(hrel))>width)  width=x;
+  padding = extra_space((width-strlen(name)+3)/2); /* includes \\n */
+  /* strcpy(res,padding); */
+  strcpy(res,"Cost centre: ");
+  strcat(res,name);
+  strcat(res,"\\n");
+  strcat(res,"Module     : ");
+  strcat(res,module);
+  strcat(res,"\\n");
+  strcat(res,"Group      : ");
+  strcat(res,group);
+  strcat(res,"\\n\\n");
+  /* padding = extra_space((width-strlen(syncs)+3)/2); */
+  //strcat(res,padding);
+  strcat(res,syncs);
+  strcat(res,head);
+  strcat(res,comp);
+  strcat(res,comm);
+  strcat(res,wait);
+  /* strcat(res,hrel); */
+  return res;
+}
+
+
+double nodeColour(object_cost *cost) {
+
+  switch (CriticalPath + CriticalType) {
+  case CRITTYPE_ABSOLUTE+CRITICAL_SYNCS:      
+  case CRITTYPE_ABSDELTA+CRITICAL_SYNCS:      
+  case CRITTYPE_RELDELTA+CRITICAL_SYNCS:      
+  case CRITTYPE_WEIGHTDELTA+CRITICAL_SYNCS:
+    return SAFEDIV(((double)cost->syncs),((double)this_syncs));
+
+  case CRITTYPE_ABSOLUTE+CRITICAL_COMP:       
+    return SAFEDIV(cost->comp_max,this_total_comp_max);
+
+  case CRITTYPE_ABSOLUTE+CRITICAL_COMM:       
+    return SAFEDIV(cost->comm_max,this_total_comm_max);
+
+  case CRITTYPE_ABSOLUTE+CRITICAL_WAIT:       
+    return SAFEDIV(cost->comp_idle_max,this_total_comp_idle_max);
+
+  case CRITTYPE_ABSOLUTE+CRITICAL_HREL:       
+    return SAFEDIV(((double) cost->hrel_max),((double)this_hrel_max));
+
+  case CRITTYPE_ABSDELTA+CRITICAL_COMP:
+    return SAFEDIV(cost->comp_max,TotalComp);
+
+  case CRITTYPE_ABSDELTA+CRITICAL_COMM:
+    return SAFEDIV(cost->comm_max,TotalComm);
+
+  case CRITTYPE_ABSDELTA+CRITICAL_WAIT:
+    return SAFEDIV(cost->comp_idle_max,TotalCompIdle);
+
+  case CRITTYPE_ABSDELTA+CRITICAL_HREL:
+    return SAFEDIV(((double) (cost->hrel_max - cost->hrel_avg)),
+                  ((double) (this_hrel_max-this_hrel_avg)));
+
+  case CRITTYPE_RELDELTA+CRITICAL_COMP:
+   return SAFEDIV((cost->comp_max-cost->comp_avg),
+                  (cost->comp_avg*DeltaNormalise));
+
+  case CRITTYPE_RELDELTA+CRITICAL_COMM:
+   return SAFEDIV((cost->comm_max-cost->comm_avg),
+           (cost->comm_avg*DeltaNormalise));
+
+  case CRITTYPE_RELDELTA+CRITICAL_WAIT:
+   return SAFEDIV((cost->comp_idle_max-cost->comp_idle_avg),
+                  (cost->comp_idle_avg*DeltaNormalise));
+
+  case CRITTYPE_RELDELTA+CRITICAL_HREL:
+    return SAFEDIV(((double) (cost->hrel_max - cost->hrel_avg)),
+                  ((double) (cost->hrel_avg*DeltaNormalise)));
+
+  case CRITTYPE_WEIGHTDELTA+CRITICAL_COMP:
+   return (SAFEDIV((cost->comp_max-cost->comp_avg),
+                   (cost->comp_avg*DeltaNormalise))*
+          SAFEDIV(cost->comp_max,this_total_comp_max));
+
+  case CRITTYPE_WEIGHTDELTA+CRITICAL_COMM:
+   return (SAFEDIV((cost->comm_max-cost->comm_avg),
+                   (cost->comm_avg*DeltaNormalise))*
+           SAFEDIV(cost->comm_max,this_total_comm_max));
+
+  case CRITTYPE_WEIGHTDELTA+CRITICAL_WAIT:
+   return (SAFEDIV((cost->comp_idle_max-cost->comp_idle_avg),
+                   (cost->comp_idle_avg*DeltaNormalise))*
+          SAFEDIV(cost->comp_idle_max,this_total_comp_idle_max));
+
+  case CRITTYPE_WEIGHTDELTA+CRITICAL_HREL:
+    return (SAFEDIV(((double) (cost->hrel_max - cost->hrel_avg)),
+                   ((double) (cost->hrel_avg*DeltaNormalise)))*
+           SAFEDIV(((double) cost->hrel_max),((double)this_hrel_max)));
+
+  }
+  return 0.0;
+}
+
+int percentToColour(double colour) {
+  int range=255,base=0;
+
+  if (!Colour) {
+    base =100;
+    range=155;
+  }
+  if      (colour>1.0) return (base+range);
+  else if (colour<0.0) return base;
+  else return (((int) (((double)range)*colour))+base);
+}
+
+/* -----------------------------------------------------------------------------
+ * Recursively draw the graph
+ * -------------------------------------------------------------------------- */
+
+static void recur_graphToDaVinci(int node,Matrix *graph,Matrix *costs,char* p_zeronodes, int mode){
+  object_cost *ptr;
+  int i,j,no_children=0,*children,colour,small;
+  char line[MAX_FUNNAME], *node_str;
+  char tempnode[MAX_FUNNAME];
+  if (Mat(int,*graph,node,node)<0) {
+    printf("r(\"%d\") ",node);
+  } else {
+    for(i=0;i<graph->cols;i++) 
+      if (node!=i && Mat_dense(*graph,node,i)) no_children++;
+  
+    if (no_children>0) {
+      children = calloc(no_children,sizeof(int));
+      if (children==NULL) {
+        fprintf(stderr,"{printDaVinci} unable to allocate %d ",no_children);
+        exit(1);
+      }
+      for((i=0,j=0);i<graph->cols;i++)
+        if (node!=i && Mat_dense(*graph,node,i)) children[j++]=i;
+
+      qsort(children,no_children,sizeof(int),
+           (int (*)(const void *,const void *)) cmp_symbol_entry);
+    }
+    ptr = &Mat(object_cost,*costs,node,0);
+    node_str=(NodeviewCompress)?
+               printCompressNode(node,ptr):
+               printUncompressNode(node,ptr);
+    printf("l(\"%d\",n(\"\",[a(\"OBJECT\",\"%s\"),",node,node_str);
+    printf("a(\"FONTFAMILY\",\"courier\"),");
+      
+
+      // hide the CAF:REPOSITORY as default
+      if (!strncmp(node_str,"Cost centre: CAF:REPOSITORY",26))
+         printf("a(\"HIDDEN\",\"true\"),"); // when uncompressed
+      if (!strncmp(node_str," CAF:REPOSITORY",12)) 
+         printf("a(\"HIDDEN\",\"true\"),"); // when compressed
+
+
+      if (mode==2)
+      {
+        if ((ptr->comm_max+ptr->comp_idle_max+ptr->comp_max) <= 0.0)
+            printf("a(\"HIDDEN\",\"true\"),");
+      }  
+      //for pruning all zero-cost nodes
+      if (mode==1)
+      {
+      if ((ptr->comm_max+ptr->comp_idle_max+ptr->comp_max) <= 0.0)
+          { fprintf(log,"Node %d %s is a candidate for deletion\n",node, node_str);
+            sprintf(tempnode,"\"%d\",",node);
+            strcat(p_zeronodes,tempnode);
+          }
+      } 
+
+    colour=percentToColour(1.0-nodeColour(ptr));
+       printf("a(\"COLOR\",\"#ff%.2x%.2x\")",colour,colour);
+    printf("],[");
+    Mat(int,*graph,node,node)=-1;
+    for(i=0;i<no_children;i++) {
+
+      printf("e(\"%d->%d\",[],",node,children[i]);
+      recur_graphToDaVinci(children[i],graph,costs,p_zeronodes,mode);
+      printf(")");
+      if (i<(no_children-1)) {printf(",");}
+    } 
+    printf("]))");
+  } 
+}
+
+
+
+static void recur_graphToDaVinci_old(int node,Matrix *graph, Matrix *costs) {
+  object_cost *ptr;
+  int i,j,no_children=0,*children,colour,small;
+  char line[MAX_FUNNAME], *node_str;
+  if (Mat(int,*graph,node,node)<0) {
+    fprintf(log,"r(\"%d\") ",node);
+    printf("r(\"%d\") ",node);
+  } else {
+    for(i=0;i<graph->cols;i++) 
+      if (node!=i && Mat_dense(*graph,node,i)) no_children++;
+  
+    if (no_children>0) {
+      children = calloc(no_children,sizeof(int));
+      if (children==NULL) {
+        fprintf(stderr,"{printDaVinci} unable to allocate %d ",no_children);
+        exit(1);
+      }
+      for((i=0,j=0);i<graph->cols;i++)
+        if (node!=i && Mat_dense(*graph,node,i)) children[j++]=i;
+
+      qsort(children,no_children,sizeof(int),
+           (int (*)(const void *,const void *)) cmp_symbol_entry);
+    }
+    ptr = &Mat(object_cost,*costs,node,0);
+    node_str=(NodeviewCompress)?
+               printCompressNode(node,ptr):
+               printUncompressNode(node,ptr);
+    fprintf(log,"l(\"%d\",n(\"\",[a(\"OBJECT\",\"%s\"),",node,node_str);
+    printf("l(\"%d\",n(\"\",[a(\"OBJECT\",\"%s\"),",node,node_str);
+    fprintf(log,"a(\"FONTFAMILY\",\"courier\"),");
+    printf("a(\"FONTFAMILY\",\"courier\"),");
+    if (symbol_table[node].type==CG_SSTEP)
+      printf("a(\"BORDER\",\"double\"),");
+    else 
+      //if (prune subgraphs of zero cost node)
+                                                            // minNodeSize hardwired
+      if ((ptr->comm_max+ptr->comp_idle_max+ptr->comp_max) < minNodeSize)
+          printf("a(\"HIDDEN\",\"true\"),");
+        
+      //if ((ptr->comm_max+ptr->comp_idle_max+ptr->comp_max) < 0.01) 
+      //    small=1; 
+      //else small=0;
+
+    colour=percentToColour(1.0-nodeColour(ptr));
+    //if (!small) 
+       fprintf(log,"a(\"COLOR\",\"#ff%.2x%.2x\")",colour,colour);
+       printf("a(\"COLOR\",\"#ff%.2x%.2x\")",colour,colour);
+    //else 
+    //   printf("a(\"COLOR\",\"yellow\"),"); 
+    fprintf(log,"],[");
+    printf("],[");
+    Mat(int,*graph,node,node)=-1;
+    for(i=0;i<no_children;i++) {
+
+      //if (!small) 
+           fprintf(log,"e(\"%d->%d\",[],",node,children[i]);
+           printf("e(\"%d->%d\",[],",node,children[i]);
+      //else 
+      //     printf("e(\"%d->%d\",[a(\"EDGECOLOR\",\"yellow\")],",node,children[i]);
+      recur_graphToDaVinci_old(children[i],graph,costs);
+      fprintf(log,")");
+      printf(")");
+      if (i<(no_children-1)) {fprintf(log,","); printf(",");}
+    } 
+    fprintf(log,"]))");
+    printf("]))");
+  } 
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Update colour
+ * -------------------------------------------------------------------------- */
+
+void updateColours(int root, Matrix *graph, Matrix *costs) {
+  int i,colour,last;
+  object_cost *ptr;
+
+  printf("graph(change_attr([");
+  for(last=costs->rows-1;last>=0;last--)
+    if (Mat_dense(*graph,last,last)) break;
+
+  for(i=0;i<costs->rows;i++) {
+    if (Mat_dense(*graph,i,i)) {
+      colour = percentToColour(1.0-nodeColour(&Mat(object_cost,*costs,i,0)));
+      printf("node(\"%d\",[a(\"COLOR\",\"#ff%.2x%.2x\")])",
+            i,colour,colour);
+      if (i<last) printf(",");    
+    }
+  }
+  printf("]))\n");
+}
+
+/* -----------------------------------------------------------------------------
+ * Parse answer from daVinci
+ * -------------------------------------------------------------------------- */
+
+davinciCmd parseDaVinciCmd(char *input) {
+  davinciCmd result;
+  char *crp;
+  char *word,*label;
+  int i;
+  
+  result.size=1;
+  for(crp=input;*crp;crp++)
+    if (*crp==',') result.size++;
+
+  crp=input;
+  word = parse_word(&crp);
+  if (Verbose) fprintf(log,"{parseDaVinciCmd}=%s size=%d\n",word,result.size);
+  if        (strcmp(word,"node_selections_labels")==0) {
+    result.type=DAVINCI_NODE;
+    result.list =calloc(result.size,sizeof(char*));
+    if (result.list==NULL) {
+      fprintf(stderr,"{parseDaVinciCmd} failed to allocate storage");
+      exit(1);
+    }
+    crp+=2;
+    i=0;
+    word = parse_quoted(&crp);
+    result.list[i++] = dup_str(word);
+    while (*crp++==',') {
+      word = parse_quoted(&crp);
+      result.list[i++] = dup_str(word);
+    }
+  } else if (strcmp(word,"icon_selection")==0) {
+    result.type=DAVINCI_ICON;
+    result.list =calloc(result.size,sizeof(char*));
+    if (result.list==NULL) {
+      fprintf(stderr,"{parseDaVinciCmd} failed to allocate storage");
+      exit(1);
+    }
+    crp++;
+    i=0;
+    word = parse_quoted(&crp);
+    result.list[i++] = dup_str(word);
+  } else if (strcmp(word,"tcl_answer")==0) {
+    result.type=DAVINCI_TCL;
+    result.list =calloc(result.size,sizeof(char*));
+    if (result.list==NULL) {
+      fprintf(stderr,"{parseDaVinciCmd} failed to allocate storage");
+      exit(1);
+    }
+    crp++;
+    i=0;
+    word = parse_quoted(&crp);
+    result.list[i++] = dup_str(word);
+  } else if (strcmp(word,"menu_selection")==0) {
+    result.type=DAVINCI_MENU;
+    result.list =calloc(result.size,sizeof(char*));
+    if (result.list==NULL) {
+      fprintf(stderr,"{parseDaVinciCmd} failed to allocate storage");
+      exit(1);
+    }
+    crp++;
+    i=0;
+    word = parse_quoted(&crp);
+    result.list[i++] = dup_str(word);
+  }else if (strcmp(word,"node_double_click")==0) {
+    result.type=DAVINCI_OK;
+  } else if (strcmp(word,"edge_selection_labels")==0)  {
+    result.type=DAVINCI_OK;
+  } else if (strcmp(word,"ok")==0)  {
+    result.type=DAVINCI_OK;
+  } else if (strcmp(word,"quit")==0)  {
+    result.type=DAVINCI_QUIT;
+  } else {
+    result.type=DAVINCI_ERROR;
+  }
+  return result;  
+}
+
+/* -----------------------------------------------------------------------------
+ * Misc.
+ * -------------------------------------------------------------------------- */
+
+
+/* Function that returns a string containing \texttt{x} spaces. */
+static char* extra_space(int x) {
+  static char space[MAX_FUNNAME+1];
+  int i;
+
+  if (Verbose) fprintf(log,"Padding is %d\n",x);
+  for(i=0;(i<x)&&(i<MAX_FUNNAME);i++) space[i]=' ';
+  space[i]='\0';
+  return space;
+}
+
+
+static char *parse_word(char **crp) {
+  static char result[MAX_FUNNAME];
+  int i=0;
+
+  while(islower(**crp) || **crp=='_') {
+    result[i++]=**crp;
+    (*crp)++;
+  }
+  result[i]='\0';
+  return result;
+}
+
+static char *parse_quoted(char **crp) {
+  static char result[MAX_FUNNAME];
+  int i=0;
+  if (**crp=='\"') {
+    (*crp)++;
+    while (**crp != '\"') {
+      result[i++]=**crp;
+      (*crp)++;
+    }
+    (*crp)++;
+  }
+  result[i]='\0';
+  return result;
+}
+
+static char *dup_str(char *xs) {
+  char *result;
+
+  if (xs==NULL) return NULL;
+  else {
+    result = malloc(strlen(xs)+1);
+    if (result==NULL) {
+      fprintf(stderr,"{dup_str}: unable to allocate bytes");
+      exit(1);
+    }
+    strcpy(result,xs);
+    return result;
+  }
+}
diff --git a/ghc/utils/prof/cgprof/daVinci.h b/ghc/utils/prof/cgprof/daVinci.h
new file mode 100644 (file)
index 0000000..3f61069
--- /dev/null
@@ -0,0 +1,95 @@
+/* ------------------------------------------------------------------------
+ * $Id: daVinci.h,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+ *                                                                     
+ *     Copyright (C) 1995-2000 University of Oxford
+ *                                                                     
+ * Permission to use, copy, modify, and distribute this software,
+ * and to incorporate it, in whole or in part, into other software,
+ * is hereby granted without fee, provided that
+ *   (1) the above copyright notice and this permission notice appear in
+ *      all copies of the source code, and the above copyright notice
+ *      appear in clearly visible form on all supporting documentation
+ *      and distribution media;
+ *   (2) modified versions of this software be accompanied by a complete
+ *      change history describing author, date, and modifications made;
+ *      and
+ *   (3) any redistribution of the software, in original or modified
+ *      form, be without fee and subject to these same conditions.
+ * --------------------------------------------------------------------- */
+
+#ifndef _DAVINCI_H_
+#define _DAVINCI_H_
+#include "symbol.h"
+#include "matrix.h"
+#include "cgprof.h"
+
+#define PAIRMAX(x,y) (((x)>(y))?(x):(y))
+
+#define SAFEDIV(x,y) (((y)==0.0)?0.0:((x)/(y)))
+
+#define DAVINCI_ERROR        0
+#define DAVINCI_OK           1
+#define DAVINCI_NODE         2
+#define DAVINCI_MENU         3
+#define DAVINCI_ICON         4
+#define DAVINCI_DOUBLE_CLICK 5
+#define DAVINCI_QUIT         6
+#define DAVINCI_TCL          7
+
+#define TCL_HREL 0
+#define TCL_COMP 1
+#define TCL_COMM 2
+#define TCL_WAIT 3
+#define TCL_EXIT 4
+
+#define INCLUDEDIR "@includedir@"
+
+typedef struct {
+  int    type;
+  char **list;
+  int size;
+} davinciCmd;
+
+
+#define CRITICAL_COMP              0
+#define CRITICAL_COMM              1
+#define CRITICAL_WAIT              2
+#define CRITICAL_HREL              3
+#define CRITICAL_SYNCS             4
+
+#define CRITTYPE_ABSOLUTE     0
+#define CRITTYPE_ABSDELTA     100
+#define CRITTYPE_RELDELTA     200
+#define CRITTYPE_WEIGHTDELTA  300
+
+extern void graphToDaVinci(int,Matrix*,Matrix *,int);
+davinciCmd  parseDaVinciCmd(char*);
+extern void cmdDaVinci(char*,...);
+extern void initDaVinci();
+extern void activateDaVinciMenu(char *);  
+extern void updateColours(int,Matrix*,Matrix*);
+extern void tclPieUpdate(object_cost *,int,int);
+extern void tclPieInit();
+
+
+extern char* lastDavinciCmd;
+extern int   NodeviewTime;
+extern int   NodeviewCompress;
+extern double TotalComp;
+extern double TotalComm;
+extern double TotalCompIdle;
+extern int    TotalSyncs;
+extern long int TotalH;
+extern char  *dateProfiled;
+extern char  *machineName;
+extern int    bsp_p;
+extern double bsp_s,bsp_l,bsp_g;
+extern int CriticalPath;
+extern int CriticalType;
+extern double minNodeSize;
+extern int bsp_p;
+extern int PrintLogo;
+extern int Colour;
+extern int DeltaNormalise;
+extern int PieCombine;
+#endif
diff --git a/ghc/utils/prof/cgprof/main.c b/ghc/utils/prof/cgprof/main.c
new file mode 100644 (file)
index 0000000..2a276fb
--- /dev/null
@@ -0,0 +1,430 @@
+/* ------------------------------------------------------------------------
+ * $Id: main.c,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+ *                                                                     
+ *     Copyright (C) 1995-2000 University of Oxford
+ *                                                                     
+ * Permission to use, copy, modify, and distribute this software,
+ * and to incorporate it, in whole or in part, into other software,
+ * is hereby granted without fee, provided that
+ *   (1) the above copyright notice and this permission notice appear in
+ *      all copies of the source code, and the above copyright notice
+ *      appear in clearly visible form on all supporting documentation
+ *      and distribution media;
+ *   (2) modified versions of this software be accompanied by a complete
+ *      change history describing author, date, and modifications made;
+ *      and
+ *   (3) any redistribution of the software, in original or modified
+ *      form, be without fee and subject to these same conditions.
+ * --------------------------------------------------------------------- */
+
+#include "config.h"
+
+#include <stdio.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "symbol.h"
+#include "cgprof.h"
+#include "matrix.h"
+#include "daVinci.h"
+
+#define NoDeletes 80
+
+int     CriticalPath=CRITICAL_SYNCS;
+int     CriticalType=CRITTYPE_ABSOLUTE;
+int     Verbose=1;
+int     NodeviewTime=1;
+int     NodeviewCompress=1;
+int     PrintLogo=1;
+int     Colour=1;
+int     DeltaNormalise=1;
+int     PieView=TCL_COMP;
+int     PieCombine=0;
+char   *Pgm;
+char   *ProfileData;
+int     NoNodes,root;
+char    usage[]="usage:  cgprof profile-data [See man 1 cgprof]";
+char    helpUrl[]="http://www.dcs.warwick.ac.uk/people/academic/Stephen.Jarvis/profiler/";
+Matrix  graph; /* NoNodes x NoNodes matrix of integers */
+Matrix  costs; /* NoNodes x 1       matrix of costs    */
+
+double   TotalComp, TotalComm, TotalCompIdle;
+int      TotalSyncs;
+long int TotalH;
+
+char    *dateProfiled, *machineName;
+double minNodeSize = 0.01;   /* i.e, don't show nodes with _combined_
+                                   comp and comm % less than this */
+double bsp_s = 74.0;
+double bsp_l = 1902;
+double bsp_g = 9.3;
+int    bsp_p;
+
+FILE *log;
+
+
+extern void printDaVinci(int);
+
+int 
+main(int argc, char *argv[]) {
+  char davinci_stdin[MAX_PROFILE_LINE_LENGTH];
+  FILE   *fptr;
+  int i,j,k,going=1,*select_nodes, select_nodes_next,MaxNoNodes;
+  davinciCmd cmd;
+  int *undo_stack, undo_stack_next;
+  float temp_f;
+  char *ptr;
+  int mode = 0;
+  char *tempstring = malloc (80);
+  char *tempstring2 = malloc (80);
+  
+
+  /* printf("Starting main routine of browser script\n"); */
+  /* fflush(stderr); */
+
+  if (argc!=14) {
+    fprintf(stderr,"The perl script bspsgprof is buggered\n");
+    exit(1);
+  }
+
+  /* Most (if not all) of these BSP specific arguments can be removed */
+
+  Pgm         = argv[0];
+  ProfileData = argv[1];
+  bsp_p       = atoi(argv[2]);
+  machineName = argv[3];
+  dateProfiled= argv[4];
+  sscanf(argv[5],"%f",&temp_f);
+  bsp_s = temp_f;
+  sscanf(argv[6],"%f",&temp_f);
+  bsp_l = temp_f;
+  sscanf(argv[7],"%f",&temp_f);
+  bsp_g = temp_f;
+  sscanf(argv[8],"%f",&temp_f);
+  minNodeSize=temp_f;
+  Verbose = atoi(argv[9]);
+  PrintLogo=atoi(argv[10]);
+  Colour=atoi(argv[11]);
+  DeltaNormalise=atoi(argv[12]);
+  MaxNoNodes=atoi(argv[13]);
+
+  /* printf("Initialisation done\n"); */
+
+  if (Verbose) sleep(10);  
+  if (!(fptr=fopen(ProfileData,"r"))) {
+    fprintf(stderr,"%s: unable to open profile data in \"%s\".\n%s\n",
+            Pgm,ProfileData,usage);
+    exit(1);
+  }
+  if (!(log=fopen("ghcprof.log","w"))) {
+    fprintf(stderr,"%s: unable to open log file for writing\n",Pgm);
+    exit(1);
+  }
+
+  /* printf("Files opened OK\n"); */
+
+  if (!fgets(davinci_stdin, MAX_PROFILE_LINE_LENGTH, stdin) || 
+       strcmp(davinci_stdin,"ok\n")) {
+    fprintf(stderr,"%s{%s}: failed to receive ok from daVinci.\n",
+           davinci_stdin,Pgm);
+    exit(1);
+  }
+
+  /* printf("Initialising daVinci\n"); */
+
+  initDaVinci();
+  
+  /* printf("Ending initialisation of daVinci\n"); */
+  if (Verbose) fprintf(log,"%s: opened profile file \"%s\".\n",Pgm,ProfileData);
+  readRawProfile(fptr,&NoNodes,MaxNoNodes);
+  fclose(fptr);
+  if (Verbose) fprintf(log,"%s: %d nodes in profile.\n",Pgm,NoNodes);
+
+  if (NoNodes<=0) {
+    fprintf(log,"%s: no call-graph profile data in \"%s\".\n"
+            "Re-run your program using the appropriate profiling flags\n",
+            Pgm,ProfileData);
+    exit(1);
+  }
+  if (Verbose) printRawProfile();
+
+  /* Do we want INHERITANCE to begin with or not? Set to yes. */
+  createConnectivityMatrix(NoNodes,&graph,&costs,&root,1);
+
+  TotalComp     = Mat(object_cost,costs,root,0).comp_max;
+  TotalComm     = Mat(object_cost,costs,root,0).comm_max;
+  TotalCompIdle = Mat(object_cost,costs,root,0).comp_idle_max;
+  TotalH        = Mat(object_cost,costs,root,0).hrel_max;
+  TotalSyncs    = Mat(object_cost,costs,root,0).syncs;
+  if (Verbose) printConnectivityMatrix(graph,costs,root);
+  fflush(log);
+  graphToDaVinci(root,&graph,&costs,0);
+  fflush(stdout);
+  undo_stack   = calloc(NoDeletes,sizeof(int));
+  select_nodes = calloc(NoNodes,sizeof(int));
+  if (undo_stack==NULL || select_nodes==NULL) {
+    fprintf(stderr,"Unable to allocate storage for undo stack\n");
+    exit(1);
+  }
+  undo_stack_next=0;
+  select_nodes_next=0;
+  // Pie chart stuff not wanted for GHC
+  // tclPieInit();
+  // tclPieUpdate(&Mat(object_cost,costs,root,0),root,PieView);
+  select_nodes_next=1;
+  select_nodes[0]=root;
+  while (fgets(davinci_stdin, MAX_PROFILE_LINE_LENGTH, stdin) && going) {
+    cmd = parseDaVinciCmd(davinci_stdin);
+    if (Verbose) fprintf(log,"From davinci=\"%s\"\n",davinci_stdin);
+    switch (cmd.type) {
+    case DAVINCI_OK:
+      continue;
+
+    case DAVINCI_QUIT:
+      going=0;
+      break;
+
+    case DAVINCI_NODE:
+      select_nodes_next=cmd.size;
+      for(i=0;((i<cmd.size) && (i<NoNodes));i++)
+        select_nodes[i]=atoi(cmd.list[i]);
+      if (select_nodes_next>0)
+        //Pie chart stuff not wanted for GHC
+        //tclPieUpdate(&Mat(object_cost,costs,select_nodes[0],0),
+        //                  select_nodes[0],
+        //                  PieView);
+      if (mode==3) 
+      {
+         mode = atoi(cmd.list[0]);
+         getNameFromSymbolTable(mode,tempstring);
+         for(ptr=tempstring;*ptr!='\0';ptr++)
+            if (*ptr=='&') *ptr=' ';
+         mode = 3;
+         strcpy(tempstring2,"window(show_status(\"");
+         strcat(tempstring2,tempstring);
+         strcat(tempstring2,"\"))");
+         cmdDaVinci(tempstring2);
+         strcpy(tempstring,"");
+         strcpy(tempstring2,"");
+      }
+      break;
+
+    case DAVINCI_MENU:
+      if (cmd.size>0) {
+        if (strcmp(cmd.list[0], "jump")==0)  {
+         if ((select_nodes_next>=0)      && 
+              (select_nodes[0]>0)         &&
+             (select_nodes[0] < NoNodes) &&
+             (Mat_dense(graph,select_nodes[0],select_nodes[0]))) {
+           cmdDaVinci("special(focus_node(\"%d\"))\n",select_nodes[0]);
+         }
+        }
+      }
+      break;
+
+    case DAVINCI_ICON:
+      if (cmd.size>0) {
+        if (strcmp(cmd.list[0], "sync")==0) {
+         CriticalPath=CRITICAL_SYNCS;
+         activateDaVinciMenu(cmd.list[0]);
+         cmdDaVinci("window(show_status(\"Graph view\"))");
+          updateColours(root,&graph,&costs);
+
+       } else if (strcmp(cmd.list[0], "comp")==0) {
+         CriticalPath=CRITICAL_COMP;
+         activateDaVinciMenu(cmd.list[0]);
+          cmdDaVinci("window(show_status(\"SCCs critical path\"))");
+          updateColours(root,&graph,&costs);
+          
+        } else if (strcmp(cmd.list[0], "comm")==0) {
+         CriticalPath=CRITICAL_COMM;
+         activateDaVinciMenu(cmd.list[0]);
+          cmdDaVinci("window(show_status(\"Computation time critical path\"))");
+          updateColours(root,&graph,&costs);
+          
+        } else if (strcmp(cmd.list[0], "wait")==0) {
+         CriticalPath=CRITICAL_WAIT;
+         activateDaVinciMenu(cmd.list[0]);
+          cmdDaVinci("window(show_status(\"Heap usage critical path\"))"); 
+          updateColours(root,&graph,&costs);
+          
+        } else if (strcmp(cmd.list[0], "hrel")==0) {
+
+          if (mode != 3)
+          {
+            cmdDaVinci("window(show_status(\"Node spy on\"))");
+            mode = 3;
+          }
+          else 
+          {
+            mode = 0;
+            cmdDaVinci("window(show_status(\"Node spy off\"))");
+          }
+
+        } else if (strcmp(cmd.list[0], "absolute")==0) {
+          /* Now deals with inheritance profile */
+         CriticalType=CRITTYPE_ABSOLUTE;
+          activateDaVinciMenu(cmd.list[0]);
+         cmdDaVinci("window(show_status(\"Inheritance profile\"))");
+          freeMat(&graph); 
+         freeMat(&costs); 
+          createConnectivityMatrix(NoNodes,&graph,&costs,&root,1);
+          graphToDaVinci(root,&graph,&costs,0);
+         cmdDaVinci("window(show_status(\"Inheritance profile\"))");
+          updateColours(root,&graph,&costs);
+
+        } else if (strcmp(cmd.list[0], "absdelta")==0) {
+          /* Now deals with flat profile */
+         CriticalType=CRITTYPE_ABSDELTA;
+          activateDaVinciMenu(cmd.list[0]);
+         cmdDaVinci("window(show_status(\"Flat profile\"))");
+          freeMat(&graph); 
+         freeMat(&costs); 
+          createConnectivityMatrix(NoNodes,&graph,&costs,&root,0);
+          graphToDaVinci(root,&graph,&costs,0);
+         cmdDaVinci("window(show_status(\"Flat profile\"))");
+          updateColours(root,&graph,&costs);
+
+        } else if (strcmp(cmd.list[0], "reldelta")==0) {
+         CriticalType=CRITTYPE_ABSOLUTE;
+          activateDaVinciMenu(cmd.list[0]);
+         cmdDaVinci("window(show_status(\"Trimmed zero-cost sub-trees\"))");
+          strcpy(cmd.list[0], "absolute");
+          activateDaVinciMenu(cmd.list[0]);
+          graphToDaVinci(root,&graph,&costs,2);
+          updateColours(root,&graph,&costs);
+         
+        } else if (strcmp(cmd.list[0], "weightdelta")==0) {
+         CriticalType=CRITTYPE_ABSOLUTE;
+          activateDaVinciMenu(cmd.list[0]);
+         cmdDaVinci("window(show_status(\"Marked zero-cost nodes ready for deletion\"))");
+          strcpy(cmd.list[0], "absolute");
+          activateDaVinciMenu(cmd.list[0]);
+          graphToDaVinci(root,&graph,&costs,1);
+          updateColours(root,&graph,&costs);
+         
+        } else if (strcmp(cmd.list[0],"help")==0) {
+          cmdDaVinci("special(show_url(\"%s\"))",helpUrl);
+
+       } else if (strcmp(cmd.list[0],"time")==0) {
+         NodeviewTime=1;
+         activateDaVinciMenu(cmd.list[0]);
+         cmdDaVinci("window(show_status(\"Cost metric view\"))");
+          graphToDaVinci(root,&graph,&costs,0);
+
+       } else if (strcmp(cmd.list[0],"percent")==0) {
+         NodeviewTime=0;
+         activateDaVinciMenu(cmd.list[0]);
+         cmdDaVinci("window(show_status(\"Percentage view\"))");
+          graphToDaVinci(root,&graph,&costs,0);
+
+       } else if (strcmp(cmd.list[0],"compress")==0) {
+         NodeviewCompress=1;
+         activateDaVinciMenu(cmd.list[0]);
+         cmdDaVinci("window(show_status(\"Compressed node view\"))");
+         cmdDaVinci("menu(layout(compact_all))");
+          graphToDaVinci(root,&graph,&costs,0);
+
+       } else if (strcmp(cmd.list[0],"uncompress")==0) {
+         NodeviewCompress=0;
+         activateDaVinciMenu(cmd.list[0]);
+         cmdDaVinci("window(show_status(\"Uncompressed node view\"))");
+          graphToDaVinci(root,&graph,&costs,0);
+
+       } else if ((strcmp(cmd.list[0],"delete")==0) ||
+                  (strcmp(cmd.list[0],"undo")==0)) {
+          if (strcmp(cmd.list[0],"delete")==0) {
+           if (undo_stack_next==0) 
+             activateDaVinciMenu("undo");
+            for(i=0;(i<select_nodes_next) && (undo_stack_next<NoNodes);i++) 
+             undo_stack[undo_stack_next++] = select_nodes[i];
+           if (undo_stack_next==NoDeletes) 
+             activateDaVinciMenu("delete");
+           cmdDaVinci("window(show_status(\"Deleted node (s)\"))");
+            select_nodes_next=0;
+         } else {
+           if (undo_stack_next==NoDeletes) 
+             activateDaVinciMenu("delete");
+           undo_stack_next--;
+           if (undo_stack_next==0) 
+             activateDaVinciMenu("undo");
+           cmdDaVinci("window(show_status(\"Undone deletion\"))");
+           select_nodes_next=1;
+           select_nodes[0]=undo_stack[undo_stack_next];
+            
+           for(i=0;i<raw_profile_next;i++)
+             raw_profile[i].active=1;
+         }
+         activateDaVinciMenu("default");
+         for(i=0;i<undo_stack_next;i++) {
+           for(j=0;j<raw_profile_next;j++) {
+              for(k=0;k<raw_profile[j].stack_size;k++) {
+                if (raw_profile[j].stack[k]==undo_stack[i])
+                 raw_profile[j].active=0;
+             }
+            }
+          }
+          cmdDaVinci("window(show_message(\"Deleting node...\"))");
+          freeMat(&graph);
+         freeMat(&costs);
+          createConnectivityMatrix(NoNodes,&graph,&costs,&root,1);
+          graphToDaVinci(root,&graph,&costs,0);
+          if (strcmp(cmd.list[0],"undo")==0) {
+            if ((select_nodes[0]>0)         &&
+               (select_nodes[0] < NoNodes) &&
+               (Mat_dense(graph,select_nodes[0],select_nodes[0]))) {
+           cmdDaVinci("special(focus_node(\"%d\"))\n",select_nodes[0]);
+           cmdDaVinci("special(select_nodes([\"%d\"]))",select_nodes[0]);
+            //Pie chart stuff not wanted for GHC
+           //tclPieUpdate(&Mat(object_cost,costs,select_nodes[0],0),
+           //         select_nodes[0],
+           //         PieView);
+            }
+          }
+       }    
+      }
+      break;
+    case DAVINCI_TCL: 
+    // This stuff can go as it is related to the input for the Pie chart tool
+      if (cmd.size>0) {
+        if        (strcmp(cmd.list[0], "comm")==0)  {
+         PieView=TCL_COMM;
+       } else if (strcmp(cmd.list[0], "comp")==0)  {
+         PieView=TCL_COMP;
+       } else if (strcmp(cmd.list[0], "hrel")==0)  {
+         PieView=TCL_HREL;
+       } else if (strcmp(cmd.list[0], "wait")==0)  {
+         PieView=TCL_WAIT;
+       } else if (strcmp(cmd.list[0], "combine")==0)  {
+         PieCombine=!PieCombine;
+        } else if (strlen(cmd.list[0])==0) {
+         break;
+       }
+       if (select_nodes_next>0) break;
+          //Added a break for compiliation above since it does not compile if 
+          //we just remove the Pie chart code 
+         //tclPieUpdate(&Mat(object_cost,costs,select_nodes[0],0),
+         //           select_nodes[0],
+         //           PieView);
+      }
+      break;
+    case DAVINCI_ERROR:  
+    default:
+      fprintf(stderr,"CGPROF error:\n"
+                     "\tCommand = %s\n"
+                    "\tError   = %s\n",lastDavinciCmd,davinci_stdin);
+      exit(1); 
+      break;
+    }
+    fflush(stdout);
+    fflush(log);
+  }  
+
+  return 0;
+}
diff --git a/ghc/utils/prof/cgprof/matrix.c b/ghc/utils/prof/cgprof/matrix.c
new file mode 100644 (file)
index 0000000..328ceeb
--- /dev/null
@@ -0,0 +1,97 @@
+/* ------------------------------------------------------------------------
+ * $Id: matrix.c,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+ *                                                                     
+ *     Copyright (C) 1995-2000 University of Oxford
+ *                                                                     
+ * Permission to use, copy, modify, and distribute this software,
+ * and to incorporate it, in whole or in part, into other software,
+ * is hereby granted without fee, provided that
+ *   (1) the above copyright notice and this permission notice appear in
+ *      all copies of the source code, and the above copyright notice
+ *      appear in clearly visible form on all supporting documentation
+ *      and distribution media;
+ *   (2) modified versions of this software be accompanied by a complete
+ *      change history describing author, date, and modifications made;
+ *      and
+ *   (3) any redistribution of the software, in original or modified
+ *      form, be without fee and subject to these same conditions.
+ * --------------------------------------------------------------------- */
+
+/* Not very clever sparse representation of a matrix. However, it will do
+ * for the call graph profiler. 
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "matrix.h"
+
+Matrix newMat(int rows,int cols, int elsize, void *zero) {
+  Matrix res;
+
+  res.elsize= elsize;
+  res.zero  = malloc(elsize);
+  if (res.zero==NULL) {
+    fprintf(stderr,"{newMat} unable to allocate storage\n");
+    exit(1);
+  }
+  memcpy(res.zero,zero,elsize);
+  res.rows  = rows;
+  res.cols  = cols;
+  res.mat=NULL;
+  return res;
+}
+
+void freeMat(Matrix *mat) {
+  Matrix_element *tmp_ptr, *ptr=mat->mat;
+  free(mat->zero);
+
+  while(ptr!=NULL) {
+    free(ptr->data);
+    tmp_ptr = ptr->next;
+    free(ptr);
+    ptr=tmp_ptr;
+  }
+}
+
+void *_Mat(Matrix *mat,int x, int y,int lineno, char *filename) {
+  Matrix_element *ptr= mat->mat;
+  if (x<0 || x>=mat->rows || y<0 || y>=mat->cols) {
+    fprintf(stderr,"Mat[%d,%d] out of bound index at line %d of \"%s\"\n",
+           x,y,lineno,filename);
+    exit(1);
+  }
+  while(ptr) {
+    if ((x==ptr->x) && (y==ptr->y)) {
+      return ptr->data;
+    }
+    ptr=ptr->next;
+  }
+  /* Not in list */
+  ptr = (Matrix_element*) malloc(sizeof(Matrix_element));
+  if (ptr==NULL) {
+    fprintf(stderr,"{_Mat} failed to allocate %d bytes\n",
+           sizeof(Matrix_element));
+    exit(1);
+  }
+  ptr->data = (void*) malloc(mat->elsize);
+  if (ptr->data==NULL) {
+    fprintf(stderr,"{_Mat} failed to allocate element of size %d bytes\n",
+           mat->elsize);
+    exit(1);
+  }
+  ptr->x=x;
+  ptr->y=y;
+  memcpy(ptr->data,mat->zero,mat->elsize);
+  ptr->next=mat->mat;
+  mat->mat=ptr;
+  return ptr->data;
+}
+
+int Mat_dense(Matrix mat,int x,int y) {
+  Matrix_element *ptr= mat.mat;
+  while (ptr) {
+    if ((x==ptr->x) && (y==ptr->y)) return 1;
+    ptr=ptr->next;
+  }
+  return 0;
+}
diff --git a/ghc/utils/prof/cgprof/matrix.h b/ghc/utils/prof/cgprof/matrix.h
new file mode 100644 (file)
index 0000000..bf70cf7
--- /dev/null
@@ -0,0 +1,42 @@
+/* ------------------------------------------------------------------------
+ * $Id: matrix.h,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+ *                                                                     
+ *     Copyright (C) 1995-2000 University of Oxford
+ *                                                                     
+ * Permission to use, copy, modify, and distribute this software,
+ * and to incorporate it, in whole or in part, into other software,
+ * is hereby granted without fee, provided that
+ *   (1) the above copyright notice and this permission notice appear in
+ *      all copies of the source code, and the above copyright notice
+ *      appear in clearly visible form on all supporting documentation
+ *      and distribution media;
+ *   (2) modified versions of this software be accompanied by a complete
+ *      change history describing author, date, and modifications made;
+ *      and
+ *   (3) any redistribution of the software, in original or modified
+ *      form, be without fee and subject to these same conditions.
+ * --------------------------------------------------------------------- */
+
+#ifndef _MATRIX_H_
+#define _MATRIX_H_
+typedef struct _Matrix_element {
+  int                     x,y;
+  void                   *data;
+  struct _Matrix_element *next;
+} Matrix_element;
+
+typedef struct {
+  int             elsize;
+  void           *zero;
+  int             rows,cols;
+  Matrix_element *mat;
+} Matrix;
+
+
+extern Matrix newMat(int,int,int,void*);
+extern void   *_Mat(Matrix*,int,int,int,char*);
+extern int    Mat_dense(Matrix,int,int);
+extern void   freeMat(Matrix *);
+
+#define Mat(t,m,i,j) (*((t*) _Mat(&(m),i,j,__LINE__,__FILE__)))
+#endif
diff --git a/ghc/utils/prof/cgprof/symbol.c b/ghc/utils/prof/cgprof/symbol.c
new file mode 100644 (file)
index 0000000..3800a69
--- /dev/null
@@ -0,0 +1,114 @@
+/* ------------------------------------------------------------------------
+ * $Id: symbol.c,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+ *                                                                     
+ *     Copyright (C) 1995-2000 University of Oxford
+ *                                                                     
+ * Permission to use, copy, modify, and distribute this software,
+ * and to incorporate it, in whole or in part, into other software,
+ * is hereby granted without fee, provided that
+ *   (1) the above copyright notice and this permission notice appear in
+ *      all copies of the source code, and the above copyright notice
+ *      appear in clearly visible form on all supporting documentation
+ *      and distribution media;
+ *   (2) modified versions of this software be accompanied by a complete
+ *      change history describing author, date, and modifications made;
+ *      and
+ *   (3) any redistribution of the software, in original or modified
+ *      form, be without fee and subject to these same conditions.
+ * --------------------------------------------------------------------- */
+
+#include "symbol.h"
+
+/* -----------------------------------------------------------------------------
+ * Data structures
+ * -------------------------------------------------------------------------- */
+int          symbol_table_next=0;
+int          symbol_table_size=0;
+name_object *symbol_table=NULL;
+
+/* -----------------------------------------------------------------------------
+ * Create/grow symbol table
+ * -------------------------------------------------------------------------- */
+
+void enlargeSymbolTable() {
+
+  if (symbol_table_size==0) {
+    symbol_table_next = 0;
+    symbol_table_size = SYMBOL_TABLE_INIT_SIZE;
+    symbol_table      = calloc(symbol_table_size,sizeof(name_object));
+  } else {
+    symbol_table_size += SYMBOL_TABLE_INIT_SIZE;
+    symbol_table       = realloc(symbol_table,
+                                symbol_table_size*sizeof(name_object));
+  }
+  if (symbol_table==NULL) {
+    fprintf(stderr,"{enlargeSymbolTable} unable to allocate %d elements",
+            symbol_table_size);
+    exit(1);
+  }
+}
+
+/* -----------------------------------------------------------------------------
+ * Lookup/add name to symbol table
+ * -------------------------------------------------------------------------- */
+
+name_id lookupSymbolTable(int type,int lineno,char* str) {
+  int i;
+  extern FILE *log;
+
+  for(i=0;i<symbol_table_next;i++) {
+    if ((type==symbol_table[i].type) && 
+        (strcmp(str,symbol_table[i].filename)==0) &&
+        (type==CG_STACK || (lineno==symbol_table[i].lineno))) {
+      return i;
+    }
+  }
+  fprintf(log,"{lookupSymbolTable} %d at %s line %d\n",type,str,lineno);
+  if (symbol_table_next==symbol_table_size) enlargeSymbolTable();
+  symbol_table[symbol_table_next].type    = type;
+  symbol_table[symbol_table_next].lineno  = lineno;
+  symbol_table[symbol_table_next].filename= malloc(1+strlen(str));
+  if (symbol_table[symbol_table_next].filename==NULL) {
+    fprintf(stderr,"{lookupSymbolTable} failed to allocate space");
+    exit(1);
+  }
+  strcpy(symbol_table[symbol_table_next].filename,str);
+  return (symbol_table_next++);
+}
+
+/* -----------------------------------------------------------------------------
+ * Comparison function to be used by \texttt{qsort}
+ * -------------------------------------------------------------------------- */
+
+int cmp_symbol_entry(const int *x, const int *y) {
+  int i;
+
+  if (symbol_table[*x].type==symbol_table[*y].type) {
+    i = strcmp(symbol_table[*x].filename,symbol_table[*y].filename);
+    if  (i==0) return (symbol_table[*x].lineno - symbol_table[*y].lineno);
+    else return i;
+  } else {
+    if (symbol_table[*x].type==CG_STACK) return 1;
+    else return -1;
+  }
+}
+
+
+/* -----------------------------------------------------------------------------
+ * Pretty print a symbol table entry
+ * -------------------------------------------------------------------------- */
+
+void printSymbolTable_entry(int idx) {
+  extern FILE *log;
+  if (symbol_table[idx].type==CG_SSTEP) {
+    fprintf(log,"(line %d of %s) ",symbol_table[idx].lineno,
+                                     symbol_table[idx].filename);
+  } else {
+    fprintf(log,"%s ",symbol_table[idx].filename);
+  }
+}
+
+void getNameFromSymbolTable(int idx, char* name) {
+  strcpy(name,symbol_table[idx].filename);
+}
+
diff --git a/ghc/utils/prof/cgprof/symbol.h b/ghc/utils/prof/cgprof/symbol.h
new file mode 100644 (file)
index 0000000..6979731
--- /dev/null
@@ -0,0 +1,58 @@
+/* ------------------------------------------------------------------------
+ * $Id: symbol.h,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+ *                                                                     
+ *     Copyright (C) 1995-2000 University of Oxford
+ *                                                                     
+ * Permission to use, copy, modify, and distribute this software,
+ * and to incorporate it, in whole or in part, into other software,
+ * is hereby granted without fee, provided that
+ *   (1) the above copyright notice and this permission notice appear in
+ *      all copies of the source code, and the above copyright notice
+ *      appear in clearly visible form on all supporting documentation
+ *      and distribution media;
+ *   (2) modified versions of this software be accompanied by a complete
+ *      change history describing author, date, and modifications made;
+ *      and
+ *   (3) any redistribution of the software, in original or modified
+ *      form, be without fee and subject to these same conditions.
+ * --------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+
+/* -----------------------------------------------------------------------------
+ * Symbol table associated with cost centres
+ * -------------------------------------------------------------------------- */
+
+#ifndef _SYMBOL_H_
+#define _SYMBOL_H_
+#define CG_STACK 42
+#define CG_SSTEP 1968
+
+
+#define MAX_PROFILE_LINE_LENGTH   10000
+#define MAX_STACK_DEPTH           60
+#define MAX_FUNNAME               80
+
+
+typedef struct {
+  int   type;    /* Either CG_STACK or CG_SSTEP */
+  int   lineno;
+  char *filename;  
+} name_object;
+
+typedef int name_id; /* i.e. index into symbol table */
+
+#define SYMBOL_TABLE_INIT_SIZE 100
+extern int          symbol_table_next;
+extern int          symbol_table_size;
+extern name_object *symbol_table;
+
+
+extern void printSymbolTable(int , int *);
+extern int cmp_symbol_entry(const int *, const int *);
+extern name_id lookupSymbolTable(int,int,char*);
+extern void printSymbolTable_entry(int);
+extern void getNameFromSymbolTable(int,char*);
+#endif
diff --git a/ghc/utils/prof/ghcprof.prl b/ghc/utils/prof/ghcprof.prl
new file mode 100644 (file)
index 0000000..55e5afe
--- /dev/null
@@ -0,0 +1,263 @@
+# -----------------------------------------------------------------------------
+# $Id: ghcprof.prl,v 1.1 2000/04/05 10:06:36 simonmar Exp $
+#
+# (c) The GHC Team 2000
+#
+# needs: INSTALLING, FPTOOLS_TOP_ABS, libdir, TARGETPLATFORM, TMPDIR
+#
+
+if ($ENV{'DAVINCIHOME'}) {
+    $davincihome = $ENV{'DAVINCIHOME'};
+    $davinci     = $davincihome . "/daVinci";
+} else {
+    print STDERR "ghcprof: DAVINCIHOME environment variable not set";
+    exit(1);
+}
+
+$machname      = ${TARGETPLATFORM};
+$bsp_s         = 10.0;
+$bsp_l         = 12;
+$bsp_g         = 13;
+$MaxNoNodes    = 1900;
+
+$icondir    = ( $INSTALLING ? "$libdir/icons" 
+                           : "$FPTOOLS_TOP_ABS/ghc/utils/prof/icons" );
+$xmlparser  = ( $INSTALLING ? "$libexecdir/xmlparser"
+                           : "$FPTOOLS_TOP_ABS/ghc/utils/prof/xmlparser/xmlparser" );
+
+$cgprof_dir = ( $INSTALLING ? "$libexecdir"
+                           : "$FPTOOLS_TOP_ABS/ghc/utils/prof/cgprof" );
+
+# where to make tmp file names?
+if ( $ENV{'TMPDIR'} ) {
+    $Tmp_prefix = $ENV{'TMPDIR'} . "/ghcprof";
+} else {
+    $Tmp_prefix ="${TMPDIR}/ghcprof";
+    $ENV{'TMPDIR'} = "${TMPDIR}"; # set the env var as well
+}
+
+# Create an new temporary filename.
+$i = $$;
+$tempfile = "";
+while (-e ($tempfile = "$Tmp_prefix" . "$i")) {
+    $i++;
+};
+
+# Delete temp. file if script is halted.
+sub quit_upon_signal { 
+    if ($tempfile ne "") {
+       print STDERR "Deleting $tempfile .. \n"; 
+       unlink "$tempfile"; 
+    }
+}
+$SIG{'INT'}  = 'quit_upon_signal';
+$SIG{'QUIT'} = 'quit_upon_signal';
+
+sub tidy_up_and_die { 
+    if ($tempfile ne "") {
+       print STDERR "Deleting $tempfile .. \n"; 
+       unlink "$tempfile"; 
+    }
+    exit($?);
+}
+
+select(STDERR); $| = 1; select(STDOUT); # no STDERR buffering, please.
+($Pgm = $0) =~ s|.*/||;
+$Version        = "v2.1 10-3-2000";
+$bug_reports_to = 'stephen.jarvis@dcs.warwick.ac.uk';
+
+$ShortUsage = "\n$Pgm usage: for basic information, try the `-help' option\n";
+
+$Usage = <<EOF
+Usage: $Pgm [option...] filename.prof
+
+Options:
+    -v          Verbose
+    -hide       (???)
+    -nologo     Omit the logo
+    -grey       Greyscale only
+    -color      Enable color (default)
+    -normalise  (???)
+EOF
+    ;
+
+$Verbose       = 0;
+$InputFile     = "";
+$date          = "";
+$nprocs        = 0;
+$hide          = 0.01;
+$Logo          = 1;
+$Colour        = 1;
+$DeltaNormalise= 2;
+
+ arg: while ($_ = $ARGV[0]) {
+     shift(@ARGV);
+     #--------HELP------------------------------------------------
+     /^-help$/   && do { print STDERR $Usage; exit(0); };
+     
+     /^-v$/      && do {$Verbose = 1; next arg;};
+     
+     /^-hide$/   && do {$hide= &grab_next_arg("-hide");
+                       if (($hide =~ /^(\d+.\d+)$/) || ($hide =~ /^(\d+)$/)) {
+                           $hide = $1/100.0;
+                       } else {
+                           print STDERR "$Pgm: -hide requires a percentage as ",
+                           "an argument\n";
+                           $Status++;
+                       }
+                       next arg;};
+     
+     /^-nologo$/    && do {$Logo  =0; next arg;};
+     /^-gr(e|a)y$/  && do {$Colour=0; next arg;};
+     /^-colou?r$/   && do {$Colour=1; next arg;};
+     /^-normalise$/ && do {$DeltaNormalise = &grab_next_arg("-normalise");
+                          if ($DeltaNormalise =~ /^(\d+)$/) {
+                              $DeltaNormalise = int($DeltaNormalise);
+                          } else {
+                              print STDERR "$Pgm: -normalise requires an integer ",
+                              "an argument\n";
+                              $Status++;
+                          }
+                          next arg;};
+     
+     /^-/           && do { print STDERR "$Pgm: unrecognised option \"",$_,"\"\n"; 
+                           $Status++;
+                       };
+     
+     if ($InputFile eq "") {
+        $InputFile = $_; next arg; 
+     } else {
+        $Status++;
+     };
+ }
+
+if ($InputFile eq "") {
+    print STDERR "$Pgm: no input file given\n";
+    $Status++;
+}  
+if ($Status>0) {
+    print STDERR $ShortUsage;
+    exit(1);
+}
+print STDERR "$Pgm: ($Version)\n" if $Verbose;
+
+# -----------------------------------------------------------------------------
+# Parse the XML
+
+# ToDo: use the real xmlparser
+# system("$xmlparser < $InputFile > $tempfile");
+# if ($? != 0) { tidy_up_and_die(); }
+
+# Stehpen's hacky replacement for xmlparser:
+
+$cc_write  = 1; 
+$ccs_write = 1;
+$scc_write = 1;
+
+open(INPUT, "<$InputFile") || tidy_up_and_die();
+open(TEMPFILE, ">$tempfile") || tidy_up_and_die();
+
+while (<INPUT>) { 
+    if (/^1 (\d+) (.*)$/)
+    {
+       if ($cc_write) { 
+           print TEMPFILE ">>cost_centre\n"; 
+           $cc_write = 0; 
+       }
+       $cc_id          = $1;
+       $name           = $2;
+       $module         = $3;
+       print TEMPFILE "$cc_id $name $module\n"; 
+    }  
+    if (/^2 (\d+) (\d+) (\d+)$/)
+    {
+       if ($ccs_write) {
+           print TEMPFILE ">>cost_centre_stack\n";
+           $ccs_write = 0;
+       }
+       $ccs_id         = $1;
+       $ccptr          = $2;
+       $ccsptr         = $3;
+       print TEMPFILE "$ccs_id $ccptr $ccsptr\n";
+    } 
+    elsif (/^2 (\d+) (\d+) (\d+) (\d+)$/)
+    {
+       if ($ccs_write) {
+           print TEMPFILE ">>cost_centre_stack\n";
+           $ccs_write = 0;
+       }
+       $ccs_id         = $1;
+       $type           = $2;
+       $ccptr          = $3;
+       $ccsptr         = $4;
+       print TEMPFILE "$ccs_id $type $ccptr $ccsptr\n";
+    } 
+    if (/^5 (\d+) (.*)$/)
+    {
+       if ($scc_write) {
+           print TEMPFILE ">>scc_sample\n";
+           $scc_write = 0;
+       }
+       $_              = $2;
+       while (/^1 (\d+) (\d+) (\d+) (\d+) (.*)$/) 
+       {
+           $rg1                = $1;
+           $rg2                = $2;
+           $rg3                = $3;
+           $rg4                = $4;
+           print TEMPFILE "$rg1 $rg2 $rg3 $rg4\n";
+           $_          = $5;
+       }       
+    }
+}
+print TEMPFILE ">>\n";
+
+close(INPUT);
+close(TEMPFILE);
+
+&readProfileHeader();
+$cmd = sprintf("%s -startappl %s 'cgprof %s %d \"%s\" ".
+              "\"%s\" %.1f %.1f %.1f %.1f %d %d %d %d %d'",
+              $davinci,$cgprof_dir,$tempfile,$nprocs,$machname,$date,
+              $bsp_s,$bsp_l,$bsp_g,$hide,$Verbose,$Logo,$Colour,
+              $DeltaNormalise,$MaxNoNodes);
+$cmd = "env DAVINCI_ICONDIR=$icondir TCL_LIBRARY=$davincihome/lib/tcl ".
+    "TK_LIBRARY=$davincihome/lib/tk DAVINCIHOME=$davincihome " . $cmd;
+print STDERR "$Pgm: exec $cmd\n" if $Verbose;
+exec $cmd;
+exit(0);
+
+sub readProfileHeader {
+    local($found);
+    
+    if (!open(PROFILE,$tempfile)) {
+       printf STDERR "$Pgm: unable to open profile file \"$tempfile\".\n";
+       $? = 1; tidy_up_and_die();
+    }
+    $found=0;
+    
+    while(<PROFILE>) {
+       if (/^F/) {
+           if (/-prof/ && /-flibrary-level\s+(\d+)/) {
+               $libtype = "P$1";
+           } elsif (/-flibrary-level\s+(\d+)/) {
+               $libtype = "O$1";
+           }
+           $found++;
+           
+       } elsif (/^P\s*/) {
+           $nprocs = int($');
+           $found++;
+           
+       } elsif (/^D\s*/) {
+           chop($date = $');
+           $found++;
+           
+       } elsif (/^X\s*/) {
+           chop($device = $');
+       }
+       last if ($found>=3);
+    }
+    close(PROFILE);
+}
diff --git a/ghc/utils/prof/icons/absdelta.xbm b/ghc/utils/prof/icons/absdelta.xbm
new file mode 100644 (file)
index 0000000..e70e372
--- /dev/null
@@ -0,0 +1,8 @@
+#define absdelta_width 18
+#define absdelta_height 18
+static unsigned char absdelta_bits[] = {
+   0xfc, 0xff, 0x00, 0x04, 0x80, 0x00, 0xe4, 0x9f, 0x00, 0x04, 0x80, 0x00,
+   0xe4, 0x9f, 0x00, 0x04, 0x83, 0x00, 0x04, 0x83, 0x00, 0x04, 0x83, 0x00,
+   0x04, 0x83, 0x00, 0x04, 0x83, 0x00, 0x04, 0x83, 0x00, 0x04, 0x83, 0x00,
+   0x04, 0x83, 0x00, 0x04, 0x83, 0x00, 0x04, 0x83, 0x00, 0xe4, 0x9f, 0x00,
+   0x04, 0x80, 0x00, 0xfc, 0xff, 0x00};
diff --git a/ghc/utils/prof/icons/absolute.xbm b/ghc/utils/prof/icons/absolute.xbm
new file mode 100644 (file)
index 0000000..045e160
--- /dev/null
@@ -0,0 +1,8 @@
+#define absolute_width 18
+#define absolute_height 18
+static unsigned char absolute_bits[] = {
+   0xfc, 0xff, 0x00, 0x04, 0x80, 0x00, 0x04, 0x80, 0x00, 0xe4, 0x9f, 0x00,
+   0x04, 0x83, 0x00, 0x04, 0x83, 0x00, 0x04, 0x83, 0x00, 0x04, 0x83, 0x00,
+   0x04, 0x83, 0x00, 0x04, 0x83, 0x00, 0x04, 0x83, 0x00, 0x04, 0x83, 0x00,
+   0x04, 0x83, 0x00, 0x04, 0x83, 0x00, 0xe4, 0x9f, 0x00, 0x04, 0x80, 0x00,
+   0x04, 0x80, 0x00, 0xfc, 0xff, 0x00};
diff --git a/ghc/utils/prof/icons/comm.xbm b/ghc/utils/prof/icons/comm.xbm
new file mode 100644 (file)
index 0000000..3f1fe94
--- /dev/null
@@ -0,0 +1,8 @@
+#define time_width 18
+#define time_height 18
+static unsigned char time_bits[] = {
+   0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x38, 0x38, 0x00, 0x8c, 0x61, 0x00,
+   0x86, 0xc1, 0x00, 0x82, 0x81, 0x00, 0x83, 0x81, 0x01, 0x81, 0x01, 0x01,
+   0x81, 0x01, 0x01, 0x81, 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x06, 0x01,
+   0x03, 0x8c, 0x01, 0x02, 0x98, 0x00, 0x06, 0xc0, 0x00, 0x0c, 0x60, 0x00,
+   0x38, 0x38, 0x00, 0xe0, 0x0f, 0x00};
diff --git a/ghc/utils/prof/icons/commslack.xbm b/ghc/utils/prof/icons/commslack.xbm
new file mode 100644 (file)
index 0000000..f53e40f
--- /dev/null
@@ -0,0 +1,8 @@
+#define commslack_width 18
+#define commslack_height 18
+static unsigned char commslack_bits[] = {
+   0xe0, 0x1f, 0x00, 0xfc, 0xff, 0x00, 0x67, 0x98, 0x03, 0x67, 0x98, 0x03,
+   0xc7, 0x8f, 0x03, 0x60, 0x18, 0x00, 0xb0, 0x37, 0x00, 0xb8, 0x77, 0x00,
+   0xbc, 0xf7, 0x00, 0x7c, 0xf8, 0x00, 0xfc, 0xff, 0x00, 0xfc, 0xff, 0x00,
+   0x00, 0x00, 0x00, 0xdc, 0xc4, 0x01, 0x48, 0x45, 0x00, 0x48, 0xc5, 0x01,
+   0x48, 0x45, 0x00, 0xdc, 0xdc, 0x01};
diff --git a/ghc/utils/prof/icons/comp.xbm b/ghc/utils/prof/icons/comp.xbm
new file mode 100644 (file)
index 0000000..923ef2f
--- /dev/null
@@ -0,0 +1,8 @@
+#define comp_width 18
+#define comp_height 18
+static unsigned char comp_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03,
+   0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x19, 0x63, 0x02, 0xa5, 0x94, 0x02,
+   0x85, 0x10, 0x02, 0x99, 0x10, 0x02, 0xa1, 0x10, 0x02, 0xa5, 0x94, 0x02,
+   0x19, 0x63, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0xff, 0xff, 0x03,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/ghc/utils/prof/icons/compress.xbm b/ghc/utils/prof/icons/compress.xbm
new file mode 100644 (file)
index 0000000..39ff2f8
--- /dev/null
@@ -0,0 +1,8 @@
+#define compress_width 18
+#define compress_height 18
+static unsigned char compress_bits[] = {
+   0x03, 0x00, 0x03, 0x07, 0x80, 0x03, 0x0e, 0xc0, 0x01, 0x9c, 0xe4, 0x00,
+   0xb8, 0x74, 0x00, 0xf0, 0x3c, 0x00, 0xe0, 0x1c, 0x00, 0xf8, 0x7c, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7c, 0x00, 0xe0, 0x1c, 0x00,
+   0xf0, 0x3c, 0x00, 0xb8, 0x74, 0x00, 0x9c, 0xe4, 0x00, 0x0e, 0xc0, 0x01,
+   0x07, 0x80, 0x03, 0x03, 0x00, 0x03};
diff --git a/ghc/utils/prof/icons/compslack.xbm b/ghc/utils/prof/icons/compslack.xbm
new file mode 100644 (file)
index 0000000..4592554
--- /dev/null
@@ -0,0 +1,8 @@
+#define compslack_width 18
+#define compslack_height 18
+static unsigned char compslack_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x08, 0x40, 0x00,
+   0xa8, 0x4a, 0x00, 0x48, 0x55, 0x00, 0xa8, 0x4a, 0x00, 0x48, 0x55, 0x00,
+   0xa8, 0x4a, 0x00, 0x08, 0x40, 0x00, 0xf8, 0x7f, 0x00, 0x80, 0x07, 0x00,
+   0x00, 0x00, 0x00, 0xdc, 0xc4, 0x01, 0x48, 0x45, 0x00, 0x48, 0xc5, 0x01,
+   0x48, 0x45, 0x00, 0xdc, 0xdc, 0x01};
diff --git a/ghc/utils/prof/icons/delete.xbm b/ghc/utils/prof/icons/delete.xbm
new file mode 100644 (file)
index 0000000..166d605
--- /dev/null
@@ -0,0 +1,8 @@
+#define delete_width 18
+#define delete_height 18
+static unsigned char delete_bits[] = {
+   0xc0, 0x0f, 0x00, 0xe0, 0x1f, 0x00, 0xf0, 0x3f, 0x00, 0x38, 0x73, 0x00,
+   0x38, 0x73, 0x00, 0xf8, 0x7f, 0x00, 0xf8, 0x7f, 0x00, 0xf0, 0x3f, 0x00,
+   0xe0, 0x1f, 0x00, 0x80, 0x07, 0x00, 0x8c, 0xc7, 0x00, 0x0c, 0xc0, 0x00,
+   0x70, 0x38, 0x00, 0x80, 0x07, 0x00, 0x70, 0x38, 0x00, 0x0c, 0xc0, 0x00,
+   0x0c, 0xc0, 0x00, 0x00, 0x00, 0x00};
diff --git a/ghc/utils/prof/icons/help.xbm b/ghc/utils/prof/icons/help.xbm
new file mode 100644 (file)
index 0000000..688e7db
--- /dev/null
@@ -0,0 +1,8 @@
+#define help_width 18
+#define help_height 18
+static unsigned char help_bits[] = {
+   0xe0, 0x1f, 0x00, 0xf0, 0x3f, 0x00, 0x70, 0x38, 0x00, 0x70, 0x38, 0x00,
+   0x70, 0x38, 0x00, 0x70, 0x38, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x1e, 0x00,
+   0x00, 0x0f, 0x00, 0x80, 0x07, 0x00, 0x80, 0x07, 0x00, 0x80, 0x07, 0x00,
+   0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x80, 0x07, 0x00,
+   0x80, 0x07, 0x00, 0x00, 0x03, 0x00};
diff --git a/ghc/utils/prof/icons/hrel.xbm b/ghc/utils/prof/icons/hrel.xbm
new file mode 100644 (file)
index 0000000..36e58a9
--- /dev/null
@@ -0,0 +1,8 @@
+#define hrel_width 18
+#define hrel_height 18
+static unsigned char hrel_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x05, 0x80, 0x02, 0xe8, 0x5c, 0x00,
+   0x10, 0x23, 0x00, 0x10, 0x23, 0x00, 0x10, 0x23, 0x00, 0xe0, 0x1c, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/ghc/utils/prof/icons/hrelslack.xbm b/ghc/utils/prof/icons/hrelslack.xbm
new file mode 100644 (file)
index 0000000..8de8f0d
--- /dev/null
@@ -0,0 +1,8 @@
+#define hrelslack_width 18
+#define hrelslack_height 18
+static unsigned char hrelslack_bits[] = {
+   0x33, 0x00, 0x00, 0x33, 0x00, 0x00, 0x33, 0x00, 0x00, 0x33, 0x00, 0x00,
+   0xbf, 0xbb, 0x00, 0xbf, 0x8a, 0x00, 0xb3, 0xba, 0x00, 0xb3, 0x89, 0x00,
+   0xb3, 0xba, 0x03, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xdc, 0xc4, 0x01, 0x48, 0x45, 0x00, 0x48, 0xc5, 0x01,
+   0x48, 0x45, 0x00, 0xdc, 0xdc, 0x01};
diff --git a/ghc/utils/prof/icons/jump.xbm b/ghc/utils/prof/icons/jump.xbm
new file mode 100644 (file)
index 0000000..0e0327d
--- /dev/null
@@ -0,0 +1,8 @@
+#define jump_width 18
+#define jump_height 18
+static unsigned char jump_bits[] = {
+   0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x42, 0x55, 0x01, 0x42, 0x00, 0x02,
+   0x7e, 0x01, 0x00, 0x88, 0x00, 0x02, 0x08, 0x01, 0x00, 0x7e, 0x7e, 0x02,
+   0x42, 0x43, 0x00, 0x42, 0x42, 0x02, 0x7e, 0x7f, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x55, 0x01, 0x00, 0x00, 0x00, 0x57, 0xdb, 0x01, 0x52, 0x55, 0x01,
+   0x52, 0xd1, 0x01, 0x73, 0x51, 0x00};
diff --git a/ghc/utils/prof/icons/mycomm.xbm b/ghc/utils/prof/icons/mycomm.xbm
new file mode 100644 (file)
index 0000000..8a3adcd
--- /dev/null
@@ -0,0 +1,8 @@
+#define comm_width 18
+#define comm_height 18
+static unsigned char comm_bits[] = {
+   0xe0, 0x1f, 0x00, 0xfc, 0xff, 0x00, 0x67, 0x98, 0x03, 0x67, 0x98, 0x03,
+   0xc7, 0x8f, 0x03, 0x60, 0x18, 0x00, 0xb0, 0x37, 0x00, 0xb8, 0x77, 0x00,
+   0xbc, 0xf7, 0x00, 0x7c, 0xf8, 0x00, 0xfc, 0xff, 0x00, 0xfc, 0xff, 0x00,
+   0x00, 0x00, 0x00, 0x8c, 0x51, 0x00, 0x52, 0xaa, 0x00, 0x42, 0xaa, 0x00,
+   0x52, 0x8a, 0x00, 0x8c, 0x89, 0x00};
diff --git a/ghc/utils/prof/icons/oxpara.xbm b/ghc/utils/prof/icons/oxpara.xbm
new file mode 100644 (file)
index 0000000..323270f
--- /dev/null
@@ -0,0 +1,198 @@
+#define oxpara_width 287
+#define oxpara_height 65
+static unsigned char oxpara_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/ghc/utils/prof/icons/percent.xbm b/ghc/utils/prof/icons/percent.xbm
new file mode 100644 (file)
index 0000000..1dd0582
--- /dev/null
@@ -0,0 +1,8 @@
+#define percent_width 18
+#define percent_height 18
+static unsigned char percent_bits[] = {
+   0x00, 0x00, 0x00, 0x38, 0x80, 0x01, 0x7c, 0xc0, 0x01, 0xfe, 0xe0, 0x00,
+   0xfe, 0x70, 0x00, 0xfe, 0x38, 0x00, 0x7c, 0x1c, 0x00, 0x38, 0x0e, 0x00,
+   0x00, 0x07, 0x00, 0x80, 0x03, 0x00, 0xc0, 0x71, 0x00, 0xe0, 0xf8, 0x00,
+   0x70, 0xfc, 0x01, 0x38, 0xfc, 0x01, 0x1c, 0xfc, 0x01, 0x0e, 0xf8, 0x00,
+   0x06, 0x70, 0x00, 0x00, 0x00, 0x00};
diff --git a/ghc/utils/prof/icons/reldelta.xbm b/ghc/utils/prof/icons/reldelta.xbm
new file mode 100644 (file)
index 0000000..4e79b68
--- /dev/null
@@ -0,0 +1,8 @@
+#define reldelta_width 18
+#define reldelta_height 18
+static unsigned char reldelta_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x06, 0x00,
+   0x0e, 0x03, 0x00, 0x91, 0x21, 0x00, 0xd1, 0x50, 0x00, 0x6a, 0x88, 0x00,
+   0x1c, 0x44, 0x01, 0x1c, 0x22, 0x02, 0x6a, 0x50, 0x00, 0xd1, 0x88, 0x00,
+   0x91, 0x41, 0x01, 0x0e, 0x23, 0x02, 0x04, 0x06, 0x00, 0x00, 0x04, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/ghc/utils/prof/icons/sync.xbm b/ghc/utils/prof/icons/sync.xbm
new file mode 100644 (file)
index 0000000..55f3e55
--- /dev/null
@@ -0,0 +1,8 @@
+#define sync_width 18
+#define sync_height 18
+static unsigned char sync_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x70, 0x00, 0x00,
+   0x20, 0x00, 0x00, 0x50, 0x00, 0x00, 0x88, 0x00, 0x00, 0x04, 0x01, 0x00,
+   0x02, 0x02, 0x00, 0x07, 0x07, 0x00, 0x02, 0x02, 0x00, 0x00, 0x05, 0x00,
+   0x80, 0x08, 0x00, 0x40, 0x10, 0x00, 0x20, 0x20, 0x00, 0x70, 0x70, 0x00,
+   0x20, 0x20, 0x00, 0x00, 0x00, 0x00};
diff --git a/ghc/utils/prof/icons/time.xbm b/ghc/utils/prof/icons/time.xbm
new file mode 100644 (file)
index 0000000..e8a7937
--- /dev/null
@@ -0,0 +1,8 @@
+#define time_width 18
+#define time_height 18
+static unsigned char time_bits[] = {
+   0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0xe0, 0x0f, 0x00, 0xf8, 0x3f, 0x00,
+   0x9c, 0x31, 0x00, 0x8c, 0x01, 0x00, 0x9c, 0x01, 0x00, 0xf8, 0x0f, 0x00,
+   0xe0, 0x3f, 0x00, 0x80, 0x39, 0x00, 0x80, 0x61, 0x00, 0x80, 0x61, 0x00,
+   0x8c, 0x71, 0x00, 0x9c, 0x39, 0x00, 0xf8, 0x1f, 0x00, 0xf0, 0x07, 0x00,
+   0x80, 0x01, 0x00, 0x80, 0x01, 0x00};
diff --git a/ghc/utils/prof/icons/time1.xbm b/ghc/utils/prof/icons/time1.xbm
new file mode 100644 (file)
index 0000000..0d2d4d7
--- /dev/null
@@ -0,0 +1,8 @@
+#define time_width 18
+#define time_height 18
+static unsigned char time_bits[] = {
+   0x80, 0x01, 0x00, 0x80, 0x01, 0x00, 0xe0, 0x1f, 0x00, 0xf0, 0x3f, 0x00,
+   0x98, 0x31, 0x00, 0x8c, 0x01, 0x00, 0x9c, 0x01, 0x00, 0xf8, 0x0f, 0x00,
+   0xe0, 0x1f, 0x00, 0x80, 0x31, 0x00, 0x80, 0x61, 0x00, 0x80, 0x61, 0x00,
+   0x80, 0x31, 0x00, 0x98, 0x19, 0x00, 0xf8, 0x0f, 0x00, 0xf0, 0x07, 0x00,
+   0x80, 0x01, 0x00, 0x80, 0x01, 0x00};
diff --git a/ghc/utils/prof/icons/uncompress.xbm b/ghc/utils/prof/icons/uncompress.xbm
new file mode 100644 (file)
index 0000000..56f1293
--- /dev/null
@@ -0,0 +1,8 @@
+#define uncompress_width 18
+#define uncompress_height 18
+static unsigned char uncompress_bits[] = {
+   0x1f, 0xe0, 0x03, 0x07, 0x80, 0x03, 0x0f, 0xc0, 0x03, 0x1d, 0xe0, 0x02,
+   0x39, 0x70, 0x02, 0x70, 0x38, 0x00, 0xe0, 0x1c, 0x00, 0x40, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0xe0, 0x1c, 0x00,
+   0x70, 0x38, 0x00, 0x39, 0x70, 0x02, 0x1d, 0xe0, 0x02, 0x0f, 0xc0, 0x03,
+   0x07, 0x80, 0x03, 0x1f, 0xe0, 0x03};
diff --git a/ghc/utils/prof/icons/undo.xbm b/ghc/utils/prof/icons/undo.xbm
new file mode 100644 (file)
index 0000000..0658dc1
--- /dev/null
@@ -0,0 +1,8 @@
+#define undo_width 18
+#define undo_height 18
+static unsigned char undo_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x95, 0x8e, 0x01, 0x95, 0x52, 0x02, 0xb5, 0x52, 0x02, 0xd5, 0x52, 0x02,
+   0x95, 0x52, 0x02, 0x97, 0x8e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+   0x00, 0x80, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01,
+   0x04, 0x00, 0x00, 0x08, 0x00, 0x00};
diff --git a/ghc/utils/prof/icons/wait.xbm b/ghc/utils/prof/icons/wait.xbm
new file mode 100644 (file)
index 0000000..b0c16fc
--- /dev/null
@@ -0,0 +1,8 @@
+#define wait_width 18
+#define wait_height 18
+static unsigned char wait_bits[] = {
+   0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0xf0, 0x3c, 0x00, 0x08, 0x40, 0x00,
+   0x0c, 0xc0, 0x00, 0x14, 0xe0, 0x00, 0x64, 0x98, 0x00, 0x84, 0x87, 0x00,
+   0x04, 0x80, 0x00, 0x04, 0x80, 0x00, 0x04, 0x80, 0x00, 0x04, 0x80, 0x00,
+   0x04, 0x80, 0x00, 0x04, 0x80, 0x00, 0x04, 0xc0, 0x00, 0x08, 0x40, 0x00,
+   0x70, 0x38, 0x00, 0x80, 0x07, 0x00};
diff --git a/ghc/utils/prof/icons/weightdelta.xbm b/ghc/utils/prof/icons/weightdelta.xbm
new file mode 100644 (file)
index 0000000..9ffa012
--- /dev/null
@@ -0,0 +1,8 @@
+#define weightdelta_width 18
+#define weightdelta_height 18
+static unsigned char weightdelta_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x06, 0x00,
+   0x0e, 0x03, 0x00, 0x91, 0x01, 0x00, 0xd1, 0x00, 0x00, 0x6a, 0x04, 0x01,
+   0x1c, 0x8a, 0x02, 0x1c, 0x8a, 0x02, 0x6a, 0x24, 0x01, 0xd1, 0x00, 0x00,
+   0x91, 0x01, 0x00, 0x0e, 0x03, 0x00, 0x04, 0x06, 0x00, 0x00, 0x04, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00};