* ggc.h (struct ggc_statistics): New type.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 29 Oct 1999 04:17:33 +0000 (04:17 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 29 Oct 1999 04:17:33 +0000 (04:17 +0000)
(ggc_get_size): New function.
(ggc_print_statistics): Likewise.
* ggc-common.c (ggc_stats): New variable.
(ggc_mark_rtx_children): Keep statistics.
(ggc_mark_tree_children): Likewise.
(ggc_print_statistics): New function.
* ggc-page.c (struct globals): Add bytes_mapped field.
(alloc_anon): Update it.
(release_pages): Likewise.
(ggc_get_size): New function.
(ggc_page_print_statistics): New function.
* ggc-simple.c (ggc_get_size): New function.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@30251 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ggc-common.c
gcc/ggc-page.c
gcc/ggc-simple.c
gcc/ggc.h

index 97e54f5..aeb66bf 100644 (file)
@@ -1,3 +1,19 @@
+Thu Oct 28 21:16:35 1999  Mark Mitchell  <mark@codesourcery.com>
+
+       * ggc.h (struct ggc_statistics): New type.
+       (ggc_get_size): New function.
+       (ggc_print_statistics): Likewise.
+       * ggc-common.c (ggc_stats): New variable.
+       (ggc_mark_rtx_children): Keep statistics.
+       (ggc_mark_tree_children): Likewise.
+       (ggc_print_statistics): New function.
+       * ggc-page.c (struct globals): Add bytes_mapped field.
+       (alloc_anon): Update it.
+       (release_pages): Likewise.
+       (ggc_get_size): New function.
+       (ggc_page_print_statistics): New function.
+       * ggc-simple.c (ggc_get_size): New function.
+       
 Fri Oct 29 06:32:44 1999  Geoffrey Keating  <geoffk@cygnus.com>
 
        * flow.c (propagate_block): When the last reference to a label
index 2d8631d..fdc0322 100644 (file)
@@ -30,6 +30,9 @@
 #include "varray.h"
 #include "ggc.h"
 
+/* Statistics about the allocation.  */
+static ggc_statistics *ggc_stats;
+
 static void ggc_mark_rtx_ptr PARAMS ((void *));
 static void ggc_mark_tree_ptr PARAMS ((void *));
 static void ggc_mark_tree_varray_ptr PARAMS ((void *));
@@ -211,10 +214,18 @@ ggc_mark_rtx_children (r)
 {
   const char *fmt;
   int i;
+  enum rtx_code code = GET_CODE (r);
+
+  /* Collect statistics, if appropriate.  */
+  if (ggc_stats)
+    {
+      ++ggc_stats->num_rtxs[(int) code];
+      ggc_stats->size_rtxs[(int) code] += ggc_get_size (r);
+    }
 
   /* ??? If (some of) these are really pass-dependant info, do we have
      any right poking our noses in?  */
-  switch (GET_CODE (r))
+  switch (code)
     {
     case JUMP_INSN:
       ggc_mark_rtx (JUMP_LABEL (r));
@@ -289,12 +300,21 @@ void
 ggc_mark_tree_children (t)
      tree t;
 {
+  enum tree_code code = TREE_CODE (t);
+
+  /* Collect statistics, if appropriate.  */
+  if (ggc_stats)
+    {
+      ++ggc_stats->num_trees[(int) code];
+      ggc_stats->size_trees[(int) code] += ggc_get_size (t);
+    }
+
   /* Bits from common.  */
   ggc_mark_tree (TREE_TYPE (t));
   ggc_mark_tree (TREE_CHAIN (t));
 
   /* Some nodes require special handling.  */
-  switch (TREE_CODE (t))
+  switch (code)
     {
     case TREE_LIST:
       ggc_mark_tree (TREE_PURPOSE (t));
@@ -349,7 +369,7 @@ ggc_mark_tree_children (t)
     }
   
   /* But in general we can handle them by class.  */
-  switch (TREE_CODE_CLASS (TREE_CODE (t)))
+  switch (TREE_CODE_CLASS (code))
     {
     case 'd': /* A decl node.  */
       ggc_mark_string (DECL_SOURCE_FILE (t));
@@ -469,3 +489,74 @@ ggc_alloc_string (contents, length)
 
   return string;
 }
+
+/* Print statistics that are independent of the collector in use.  */
+
+void
+ggc_print_statistics (stream, stats)
+     FILE *stream;
+     ggc_statistics *stats;
+{
+  int code;
+
+  /* Set the pointer so that during collection we will actually gather
+     the statistics.  */
+  ggc_stats = stats;
+
+  /* Then do one collection to fill in the statistics.  */
+  ggc_collect ();
+
+  /* Total the statistics.  */
+  for (code = 0; code < MAX_TREE_CODES; ++code)
+    {
+      stats->total_num_trees += stats->num_trees[code];
+      stats->total_size_trees += stats->size_trees[code];
+    }
+  for (code = 0; code < NUM_RTX_CODE; ++code)
+    {
+      stats->total_num_rtxs += stats->num_rtxs[code];
+      stats->total_size_rtxs += stats->size_rtxs[code];
+    }
+
+  /* Print the statistics for trees.  */
+  fprintf (stream, "%-22s%-16s%-16s%-7s\n", "Code", 
+          "Number", "Bytes", "% Total");
+  for (code = 0; code < MAX_TREE_CODES; ++code)
+    if (ggc_stats->num_trees[code]) 
+      {
+       fprintf (stream, "%s%*s%-15u %-15u %7.3f\n", 
+                tree_code_name[code],
+                22 - strlen (tree_code_name[code]), "",
+                ggc_stats->num_trees[code],
+                ggc_stats->size_trees[code],
+                (100 * ((double) ggc_stats->size_trees[code]) 
+                 / ggc_stats->total_size_trees));
+      }
+  fprintf (stream,
+          "%-22s%-15u %-15u\n", "Total",
+          ggc_stats->total_num_trees,
+          ggc_stats->total_size_trees);
+
+  /* Print the statistics for RTL.  */
+  fprintf (stream, "\n%-22s%-16s%-16s%-7s\n", "Code", 
+          "Number", "Bytes", "% Total");
+  for (code = 0; code < NUM_RTX_CODE; ++code)
+    if (ggc_stats->num_rtxs[code]) 
+      {
+       fprintf (stream, "%s%*s%-15u %-15u %7.3f\n", 
+                rtx_name[code],
+                22 - strlen (rtx_name[code]), "",
+                ggc_stats->num_rtxs[code],
+                ggc_stats->size_rtxs[code],
+                (100 * ((double) ggc_stats->size_rtxs[code]) 
+                 / ggc_stats->total_size_rtxs));
+      }
+  fprintf (stream,
+          "%-22s%-15u %-15u\n", "Total",
+          ggc_stats->total_num_rtxs,
+          ggc_stats->total_size_rtxs);
+
+
+  /* Don't gather statistics any more.  */
+  ggc_stats = NULL;
+}
index f034a4f..c1cef10 100644 (file)
@@ -226,6 +226,9 @@ static struct globals
   /* Bytes currently allocated at the end of the last collection.  */
   size_t allocated_last_gc;
 
+  /* Total amount of memory mapped.  */
+  size_t bytes_mapped;
+
   /* The current depth in the context stack.  */
   unsigned char context_depth;
 
@@ -444,6 +447,9 @@ alloc_anon (pref, size)
 #endif /* HAVE_VALLOC */
 #endif /* HAVE_MMAP */
 
+  /* Remember that we allocated this memory.  */
+  G.bytes_mapped += size;
+
   return page;
 }
 
@@ -565,6 +571,7 @@ release_pages ()
       else
        {
          munmap (start, len);
+         G.bytes_mapped -= len;
          start = p->page;
          len = p->bytes;
        }
@@ -573,6 +580,7 @@ release_pages ()
     }
 
   munmap (start, len);
+  G.bytes_mapped -= len;
 #else
 #ifdef HAVE_VALLOC
   page_entry *p, *next;
@@ -581,6 +589,7 @@ release_pages ()
     {
       next = p->next;
       free (p->page);
+      G.bytes_mapped -= p->bytes;
       free (p);
     }
 #endif /* HAVE_VALLOC */
@@ -778,6 +787,14 @@ ggc_mark_if_gcable (p)
   if (p && ggc_allocated_p (p))
     ggc_set_mark (p);
 }
+
+size_t
+ggc_get_size (p)
+     void *p;
+{
+  page_entry *pe = lookup_page_table_entry (p);
+  return 1 << pe->order;
+}
 \f
 /* Initialize the ggc-mmap allocator.  */
 void
@@ -1088,3 +1105,51 @@ ggc_collect ()
               (unsigned long) G.allocated / 1024, time * 1e-6);
     }
 }
+
+/* Print allocation statistics.  */
+
+void
+ggc_page_print_statistics ()
+{
+  struct ggc_statistics stats;
+  int i;
+
+  /* Clear the statistics.  */
+  bzero (&stats, sizeof (stats));
+  
+  /* Make sure collection will really occur.  */
+  G.allocated_last_gc = 0;
+
+  /* Collect and print the statistics common across collectors.  */
+  ggc_print_statistics (stderr, &stats);
+
+  /* Collect some information about the various sizes of 
+     allocation.  */
+  fprintf (stderr, "\n%-4s%-16s%-16s\n", "Log", "Allocated", "Used");
+  for (i = 0; i < HOST_BITS_PER_PTR; ++i)
+    {
+      page_entry *p;
+      size_t allocated;
+      size_t in_use;
+
+      /* Skip empty entries.  */
+      if (!G.pages[i])
+       continue;
+
+      allocated = in_use = 0;
+
+      /* Figure out the total number of bytes allocated for objects of
+        this size, and how many of them are actually in use.  */
+      for (p = G.pages[i]; p; p = p->next)
+       {
+         allocated += p->bytes;
+         in_use += 
+           (OBJECTS_PER_PAGE (i) - p->num_free_objects) * (1 << i);
+       }
+      fprintf (stderr, "%-3d %-15u %-15u\n", i, allocated, in_use);
+    }
+
+  /* Print out some global information.  */
+  fprintf (stderr, "\nTotal bytes marked: %u\n", G.allocated);
+  fprintf (stderr, "Total bytes mapped: %u\n", G.bytes_mapped);
+}
index f665487..194863e 100644 (file)
@@ -253,6 +253,15 @@ ggc_mark_if_gcable (p)
   G.objects += 1;
 }
 
+size_t
+ggc_get_size (p)
+     void *p;
+{
+  struct ggc_mem *x 
+    = (struct ggc_mem *) ((char *)p - offsetof (struct ggc_mem, u));
+  return x->size;
+}
+
 static void
 clear_marks (x)
      struct ggc_mem *x;
index b2cfb27..2c12a13 100644 (file)
--- a/gcc/ggc.h
+++ b/gcc/ggc.h
@@ -165,3 +165,36 @@ void mark_expr_status PROTO ((struct expr_status *));
 void mark_stmt_status PROTO ((struct stmt_status *));
 void mark_varasm_status PROTO ((struct varasm_status *));
 void mark_optab PROTO ((void *));
+
+/* Statistics.  */
+
+/* This structure contains the statistics common to all collectors.
+   Particular collectors can extend this structure.  */
+typedef struct ggc_statistics 
+{
+  /* The Ith element is the number of nodes allocated with code I.  */
+  unsigned num_trees[256];
+  /* The Ith element is the number of bytes allocated by nodes with 
+     code I.  */
+  size_t size_trees[256];
+  /* The Ith element is the number of nodes allocated with code I.  */
+  unsigned num_rtxs[256];
+  /* The Ith element is the number of bytes allocated by nodes with 
+     code I.  */
+  size_t size_rtxs[256];
+  /* The total number of tree nodes allocated.  */
+  unsigned total_num_trees;
+  /* The total size of the tree nodes allocated.  */
+  size_t total_size_trees;
+  /* The total number of RTL nodes allocated.  */
+  unsigned total_num_rtxs;
+  /* The total size of the RTL nodes allocated.  */
+  size_t total_size_rtxs;
+} ggc_statistics;
+
+/* Return the number of bytes allocated at the indicated address.  */
+size_t ggc_get_size PROTO ((void *));
+
+/* Used by the various collectors to gather and print statistics that
+   do not depend on the collector in use.  */
+void ggc_print_statistics PROTO ((FILE *, ggc_statistics *));