public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [tuples] memory statistics gathering for tuples
@ 2008-03-11 19:13 Aldy Hernandez
  2008-03-12 15:38 ` Diego Novillo
  0 siblings, 1 reply; 4+ messages in thread
From: Aldy Hernandez @ 2008-03-11 19:13 UTC (permalink / raw)
  To: dnovillo, gcc-patches

It seems everything I try to fix brings about a whole slew of ancillary
fixes.

This patch adds memory statistics for tuples which can be seen when
configuring with --enable-gather-detailed-mem-stats and passing
-fmem-report to the compiler.

I will be using this to benchmark the memory comsumption of the tuples
branch.

Diego, are you ok with this?

I will be committing once tests finish.

	* tree-phinodes.c (allocate_phi_node): Update for tuples.
	* gimplify.c (gimplify_function_tree): Dump memory stats.
	* gimple.c:  Declare gimple_alloc_counts, gimple_alloc_sizes,
	and gimple_alloc_kind_names.
	(gimple_alloc): Gather statistics for tuples.
	(gimple_build_asm_1): Same.
	(gimple_seq_alloc): Same.
	(dump_gimple_statistics): New.
	* gimple.h: Define gimple_alloc_kind.
	(gimple_alloc_kind): New.
	(dump_gimple_statistics): Protoize.
	* tree-ssa-copy.c (replace_exp_1): Mark for_propagation as unused.

Index: tree-phinodes.c
===================================================================
--- tree-phinodes.c	(revision 133117)
+++ tree-phinodes.c	(working copy)
@@ -157,8 +157,11 @@ allocate_phi_node (size_t len)
       phi = ggc_alloc (size);
 #ifdef GATHER_STATISTICS
       phi_nodes_created++;
-      tree_node_counts[(int) phi_kind]++;
-      tree_node_sizes[(int) phi_kind] += size;
+	{
+	  enum gimple_alloc_kind kind = gimple_alloc_kind (GIMPLE_PHI);
+          gimple_alloc_counts[(int) kind]++;
+          gimple_alloc_sizes[(int) kind] += size;
+	}
 #endif
     }
 
Index: gimplify.c
===================================================================
--- gimplify.c	(revision 133117)
+++ gimplify.c	(working copy)
@@ -6833,6 +6833,15 @@ gimplify_function_tree (tree fndecl)
 
   current_function_decl = oldfn;
   pop_cfun ();
+#ifdef GATHER_STATISTICS
+  if (mem_report)
+    {
+      fprintf (stderr, "Memory consumption after gimplification for [%s]\n",
+	  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
+      dump_tree_statistics ();
+      dump_gimple_statistics ();
+    }
+#endif
 }
 
 
Index: tree-ssa-copy.c
===================================================================
--- tree-ssa-copy.c	(revision 133117)
+++ tree-ssa-copy.c	(working copy)
@@ -302,7 +302,8 @@ merge_alias_info (tree orig_name, tree n
    replacement is done to propagate a value or not.  */
 
 static void
-replace_exp_1 (use_operand_p op_p, tree val, bool for_propagation)
+replace_exp_1 (use_operand_p op_p, tree val,
+    	       bool for_propagation ATTRIBUTE_UNUSED)
 {
   tree op = USE_FROM_PTR (op_p);
 
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 133117)
+++ Makefile.in	(working copy)
@@ -201,6 +201,7 @@ dse.o-warn = -Wno-uninitialized
 ebitmap.o-warn = -Wno-uninitialized
 lower-subreg.o-warn = -Wno-uninitialized
 tree-chrec.o-warn = -Wno-uninitialized
+tree-ssa-structalias.o-warn = -Wno-uninitialized
 varasm.o-warn = -Wno-error
 
 # All warnings have to be shut off in stage1 if the compiler used then
Index: gimple.c
===================================================================
--- gimple.c	(revision 133117)
+++ gimple.c	(working copy)
@@ -42,6 +42,23 @@ const char *const gimple_code_name[] = {
 };
 #undef DEFGSCODE
 
+#ifdef GATHER_STATISTICS
+/* Gimple stats.  */
+
+int gimple_alloc_counts[(int) gimple_alloc_kind_all];
+int gimple_alloc_sizes[(int) gimple_alloc_kind_all];
+
+/* Keep in sync with gimple.h:enum gimple_alloc_kind.  */
+static const char * const gimple_alloc_kind_names[] = {
+    "assignments",
+    "phi nodes",
+    "conditionals",
+    "sequences",
+    "everything else"
+};
+
+#endif /* GATHER_STATISTICS */
+
 /* Keep function bodies in the array GIMPLE_BODIES_VEC and use the
    pointer map GIMPLE_BODIES_MAP to quickly map a given FUNCTION_DECL
    to its corresponding position in the array of GIMPLE bodies.  */
@@ -173,6 +190,15 @@ static gimple
 gimple_alloc (enum gimple_code code)
 {
   size_t size = gimple_size (code);
+
+#ifdef GATHER_STATISTICS
+  enum gimple_alloc_kind kind = gimple_alloc_kind (code);
+
+  gimple_alloc_counts[(int) kind]++;
+  /* Statements with operands take more space.  Add that later.  */
+  gimple_alloc_sizes[(int) kind] += size;
+#endif
+
   gimple stmt = ggc_alloc_cleared (size);
   gimple_set_code (stmt, code);
   return stmt;
@@ -186,9 +212,14 @@ gimple_alloc (enum gimple_code code)
 static void
 gimple_alloc_ops (gimple stmt, size_t num_ops)
 {
-  stmt->with_ops.op = ggc_alloc_cleared (sizeof (tree) * num_ops);
+  unsigned int size = sizeof (tree) * num_ops;
+
+  stmt->with_ops.op = ggc_alloc_cleared (size);
   stmt->with_ops.num_ops = num_ops;
   stmt->with_ops.modified = 1;
+#ifdef GATHER_STATISTICS
+  gimple_alloc_sizes[(int) gimple_alloc_kind (gimple_code (stmt))] += size;
+#endif
 }
 
 
@@ -485,12 +516,17 @@ gimple_build_asm_1 (const char *string, 
                     size_t nclobbers)
 {
   gimple p;
+  int size = strlen (string);
+
   p = gimple_build_with_ops (GIMPLE_ASM, 0, ninputs + noutputs + nclobbers);
 
   p->gimple_asm.ni = ninputs;
   p->gimple_asm.no = noutputs;
   p->gimple_asm.nc = nclobbers;
-  p->gimple_asm.string = ggc_alloc_string (string, -1);
+  p->gimple_asm.string = ggc_alloc_string (string, size);
+#ifdef GATHER_STATISTICS
+  gimple_alloc_sizes[(int) gimple_alloc_kind (GIMPLE_ASM)] += size;
+#endif
   
   return p;
 }
@@ -1006,7 +1042,13 @@ gimple_seq_alloc (void)
       memset (seq, 0, sizeof (*seq));
     }
   else
-    seq = (gimple_seq) ggc_alloc_cleared (sizeof (*seq));
+    {
+      seq = (gimple_seq) ggc_alloc_cleared (sizeof (*seq));
+#ifdef GATHER_STATISTICS
+      gimple_alloc_counts[(int) gimple_alloc_kind_seq]++;
+      gimple_alloc_sizes[(int) gimple_alloc_kind_seq] += sizeof (*seq);
+#endif
+    }
 
   return seq;
 }
@@ -1954,4 +1996,31 @@ gimple_could_trap_p (gimple s)
 
 }
 
+
+/* Print debugging information for gimple stmts generated.  */
+
+void
+dump_gimple_statistics (void)
+{
+#ifdef GATHER_STATISTICS
+  int i, total_tuples = 0, total_bytes = 0;
+
+  fprintf (stderr, "\nGIMPLE statements\n");
+  fprintf (stderr, "Kind                   Stmts      Bytes\n");
+  fprintf (stderr, "---------------------------------------\n");
+  for (i = 0; i < (int) gimple_alloc_kind_all; ++i)
+    {
+      fprintf (stderr, "%-20s %7d %10d\n", gimple_alloc_kind_names[i],
+	  gimple_alloc_counts[i], gimple_alloc_sizes[i]);
+      total_tuples += gimple_alloc_counts[i];
+      total_bytes += gimple_alloc_sizes[i];
+    }
+  fprintf (stderr, "---------------------------------------\n");
+  fprintf (stderr, "%-20s %7d %10d\n", "Total", total_tuples, total_bytes);
+  fprintf (stderr, "---------------------------------------\n");
+#else
+  fprintf (stderr, "No gimple statistics\n");
+#endif
+}
+
 #include "gt-gimple.h"
Index: gimple.h
===================================================================
--- gimple.h	(revision 133117)
+++ gimple.h	(working copy)
@@ -3072,4 +3072,40 @@ tree walk_gimple_stmt (gimple_stmt_itera
 		       struct walk_stmt_info *);
 tree walk_gimple_op (gimple, walk_tree_fn, struct walk_stmt_info *);
 
+#ifdef GATHER_STATISTICS
+/* Enum and arrays used for allocation stats.  Keep in sync with
+   gimple.c:gimple_alloc_kind_names.  */
+enum gimple_alloc_kind
+{
+  gimple_alloc_kind_assign,	/* Assignments.  */
+  gimple_alloc_kind_phi,	/* PHI nodes.  */
+  gimple_alloc_kind_cond,	/* Conditionals.  */
+  gimple_alloc_kind_seq,	/* Sequences.  */
+  gimple_alloc_kind_rest,	/* Everything else.  */
+  gimple_alloc_kind_all
+};
+
+extern int gimple_alloc_counts[];
+extern int gimple_alloc_sizes[];
+
+/* Return the allocation kind for a given stmt CODE.  */
+static inline enum gimple_alloc_kind
+gimple_alloc_kind (enum gimple_code code)
+{
+  switch (code)
+    {
+  case GIMPLE_ASSIGN:
+    return gimple_alloc_kind_assign;
+  case GIMPLE_PHI:
+    return gimple_alloc_kind_phi;
+  case GIMPLE_COND:
+    return gimple_alloc_kind_cond;
+  default:
+    return gimple_alloc_kind_rest;
+    }
+}
+#endif /* GATHER_STATISTICS */
+
+extern void dump_gimple_statistics (void);
+
 #endif  /* GCC_GIMPLE_H */

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [tuples] memory statistics gathering for tuples
  2008-03-11 19:13 [tuples] memory statistics gathering for tuples Aldy Hernandez
@ 2008-03-12 15:38 ` Diego Novillo
  2008-03-14 15:03   ` Aldy Hernandez
  0 siblings, 1 reply; 4+ messages in thread
From: Diego Novillo @ 2008-03-12 15:38 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc-patches

On 3/11/08 12:13 PM, Aldy Hernandez wrote:

> I will be using this to benchmark the memory comsumption of the tuples
> branch.
 >
 > Diego, are you ok with this?

Sure.  A few things to keep in mind when doing this:

1- Do not expect big savings.  Projections are in the single digits %.

2- Make sure you disable in mainline the same code paths disabled in the 
branch.

3- The easiest approach will probably be comparing statement lists 
versus gimple sequences.  We still haven't gone through making sure we 
release all the expression trees that are gimplified.

> @@ -186,9 +212,14 @@ gimple_alloc (enum gimple_code code)
>  static void
>  gimple_alloc_ops (gimple stmt, size_t num_ops)
>  {
> -  stmt->with_ops.op = ggc_alloc_cleared (sizeof (tree) * num_ops);
> +  unsigned int size = sizeof (tree) * num_ops;

Here you're just counting the size of the pointer.  You need to call 
tree_code_size for each operand added.

Looks OK, otherwise.

One way of making sure these numbers are OK is to count manually a few 
statements.  There are three components:

- Size of each statement.  The size of the tuple plus the aggregated 
sizes of its operands.

- Size of sequences.  Size of the gimple_seq_nodes * number of 
statements + size of statements * number of statements.

- Sizes of basic blocks.  Size of basic block plus size of the contained 
sequence.


Diego.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [tuples] memory statistics gathering for tuples
  2008-03-12 15:38 ` Diego Novillo
@ 2008-03-14 15:03   ` Aldy Hernandez
  2008-03-14 15:25     ` Diego Novillo
  0 siblings, 1 reply; 4+ messages in thread
From: Aldy Hernandez @ 2008-03-14 15:03 UTC (permalink / raw)
  To: Diego Novillo; +Cc: gcc-patches

> 3- The easiest approach will probably be comparing statement lists versus 
> gimple sequences.  We still haven't gone through making sure we release all 
> the expression trees that are gimplified.

Yes, I'm noticing benchmarking is going to be non-trivial, and probably
not an exact science until we have exact code paths, and we can
benchmark right before RTL generation, not after gimplification like I
will be forced to do now.

I think comparing statement lists versus gimple sequences will be the
most straightforward way.  Of course I will have to adjust the size of
tuples for extra things we have in there, like USE/DEF information, BB
information, etc.

>> @@ -186,9 +212,14 @@ gimple_alloc (enum gimple_code code)
>>  static void
>>  gimple_alloc_ops (gimple stmt, size_t num_ops)
>>  {
>> -  stmt->with_ops.op = ggc_alloc_cleared (sizeof (tree) * num_ops);
>> +  unsigned int size = sizeof (tree) * num_ops;
>
> Here you're just counting the size of the pointer.  You need to call 
> tree_code_size for each operand added.

Are you sure?  It looks like the tree counterpart is only adding
pointers for operands.  See tree_code_size:

    case tcc_reference:   /* a reference */
    case tcc_expression:  /* an expression */
    case tcc_statement:   /* an expression with side effects */
    case tcc_comparison:  /* a comparison expression */
    case tcc_unary:       /* a unary arithmetic expression */
    case tcc_binary:      /* a binary arithmetic expression */
      return (sizeof (struct tree_exp)
	      + (TREE_CODE_LENGTH (code) - 1) * sizeof (tree));

    case tcc_gimple_stmt:
      return (sizeof (struct gimple_stmt)
	      + (TREE_CODE_LENGTH (code) - 1) * sizeof (char *));

Aldy

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [tuples] memory statistics gathering for tuples
  2008-03-14 15:03   ` Aldy Hernandez
@ 2008-03-14 15:25     ` Diego Novillo
  0 siblings, 0 replies; 4+ messages in thread
From: Diego Novillo @ 2008-03-14 15:25 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc-patches

On 3/14/08 8:00 AM, Aldy Hernandez wrote:
>> 3- The easiest approach will probably be comparing statement lists versus 
>> gimple sequences.  We still haven't gone through making sure we release all 
>> the expression trees that are gimplified.
> 
> Yes, I'm noticing benchmarking is going to be non-trivial, and probably
> not an exact science until we have exact code paths, and we can
> benchmark right before RTL generation, not after gimplification like I
> will be forced to do now.

Yes, there are many things that have changed place, so we have to make 
sure we count the exact same thing in trees and tuples.

While I don't expect huge memory savings, calibrating this should not be 
hard.  If you find that tuple sizes seem bigger than trees, it's almost 
a certainty that the counts are not being collected right.  In any case, 
memory savings is going to be just a side-effect of the redesign, it's 
not one of the important parameters in my mind.  The only blocker would 
be if tuples result in worse memory utilization or compile-time performance.

> I think comparing statement lists versus gimple sequences will be the
> most straightforward way.  Of course I will have to adjust the size of
> tuples for extra things we have in there, like USE/DEF information, BB
> information, etc.

Yeah, or make sure that we also count the size of stmt_ann() in trees. 
And not just sizeof(), we need to add up all the sizes for individual 
fields in the annotation.

> 
>>> @@ -186,9 +212,14 @@ gimple_alloc (enum gimple_code code)
>>>  static void
>>>  gimple_alloc_ops (gimple stmt, size_t num_ops)
>>>  {
>>> -  stmt->with_ops.op = ggc_alloc_cleared (sizeof (tree) * num_ops);
>>> +  unsigned int size = sizeof (tree) * num_ops;
>> Here you're just counting the size of the pointer.  You need to call 
>> tree_code_size for each operand added.
> 
> Are you sure?  It looks like the tree counterpart is only adding
> pointers for operands.  See tree_code_size:

Oh, right.  The operands are always counted separately in each of their 
own categories.


Diego.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-03-14 15:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-11 19:13 [tuples] memory statistics gathering for tuples Aldy Hernandez
2008-03-12 15:38 ` Diego Novillo
2008-03-14 15:03   ` Aldy Hernandez
2008-03-14 15:25     ` Diego Novillo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).