Re: [PATCH] split tree_type, a.k.a. tuplifying types

2011-05-24 Thread Tom de Vries
On 05/23/2011 05:04 PM, Nathan Froyd wrote:
 On 05/22/2011 02:24 PM, Tom de Vries wrote:
 Now that struct tree_type does not exist anymore, 'sizeof (struct tree_type)'
 generates an error in the following assert in fold_checksum_tree:
 ...
   gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree)
 = sizeof (struct tree_function_decl))
 sizeof (struct tree_type) = sizeof (struct 
 tree_function_decl));
 ...

 This error is triggered with -enable-checking=fold.
 
 Doh.  Thanks for the report.
 
 The easy fix is s/tree_type/tree_type_non_common/.  But I don't see why the
 assert has to even care about tree_type; doesn't:
 
   gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree)
   = sizeof (union tree_node));
 
 accomplish the same thing?
 
 -Nathan
 
 

I don't know for sure what the assert is trying to check, but I'm guessing it's
trying to check that the memcpys are save. A naive implementation would be:

Index: fold-const.c
===
--- fold-const.c(revision 173703)
+++ fold-const.c(working copy)
@@ -13792,6 +13789,7 @@ recursive_label:
DECL_ASSEMBLER_NAME_SET_P (expr))
 {
   /* Allow DECL_ASSEMBLER_NAME to be modified.  */
+  gcc_assert (tree_size (expr) = sizeof (buf));
   memcpy ((char *) buf, expr, tree_size (expr));
   SET_DECL_ASSEMBLER_NAME ((tree)buf, NULL);
   expr = (tree) buf;
@@ -13805,6 +13803,7 @@ recursive_label:
 {
   /* Allow these fields to be modified.  */
   tree tmp;
+  gcc_assert (tree_size (expr) = sizeof (buf));
   memcpy ((char *) buf, expr, tree_size (expr));
   expr = tmp = (tree) buf;
   TYPE_CONTAINS_PLACEHOLDER_INTERNAL (tmp) = 0;

But that turns it into a runtime check.

On the other hand, I'm not sure the original assert still makes sense. Neither
tcc_type nor tcc_declaration have variable size, so the '5 * sizeof (tree)' does
not seem applicable anymore.

If we want checks cheaper than the naive, but more maintainable than the
current, we would want something like:

+  gcc_assert (tree_class_max_size (tcc_declaration) = sizeof (buf));
+  gcc_assert (tree_class_max_size (tcc_type) = sizeof (buf));

We would want those checks moved out of the hot path, and we would need to
implement and maintain tree_class_max_size alongside tree_size and
tree_code_size.  But I'm not sure it's worth the effort.

Thanks,
- Tom


Re: [PATCH] split tree_type, a.k.a. tuplifying types

2011-05-23 Thread Nathan Froyd
On 05/22/2011 02:24 PM, Tom de Vries wrote:
 Now that struct tree_type does not exist anymore, 'sizeof (struct tree_type)'
 generates an error in the following assert in fold_checksum_tree:
 ...
   gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree)
  = sizeof (struct tree_function_decl))
  sizeof (struct tree_type) = sizeof (struct 
 tree_function_decl));
 ...
 
 This error is triggered with -enable-checking=fold.

Doh.  Thanks for the report.

The easy fix is s/tree_type/tree_type_non_common/.  But I don't see why the
assert has to even care about tree_type; doesn't:

  gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree)
  = sizeof (union tree_node));

accomplish the same thing?

-Nathan




Re: [PATCH] split tree_type, a.k.a. tuplifying types

2011-05-22 Thread Tom de Vries
Hi,

Now that struct tree_type does not exist anymore, 'sizeof (struct tree_type)'
generates an error in the following assert in fold_checksum_tree:
...
  gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree)
   = sizeof (struct tree_function_decl))
   sizeof (struct tree_type) = sizeof (struct 
tree_function_decl));
...

This error is triggered with -enable-checking=fold.

Thanks,
- Tom


Re: [PATCH] split tree_type, a.k.a. tuplifying types

2011-05-11 Thread Richard Guenther
On Tue, May 10, 2011 at 7:50 PM, Nathan Froyd froy...@codesourcery.com wrote:
 On Tue, May 10, 2011 at 02:28:06PM -0300, Diego Novillo wrote:
 On Tue, May 10, 2011 at 13:15, Nathan Froyd froy...@codesourcery.com wrote:
  Other types can of course be shrunk, but the memory savings from doing
  so will be negligible

 Have you done any measurements on the potential savings?

 Only back-of-the-envelope.  I will try to get some numbers after we
 start saving memory. :)

  +static void
  +lto_input_ts_type_common_tree_pointers (struct lto_input_block *ib,
  +                                       struct data_in *data_in, tree expr)
  +{
  +  TYPE_SIZE (expr) = lto_input_tree (ib, data_in);
  +  TYPE_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
  +  TYPE_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
  +  TYPE_NAME (expr) = lto_input_tree (ib, data_in);
  +  /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO.  */

 Add some wording as to why not?  This was copied from existing
 comments, but I do not remember why we were doing this.  Not too
 critical, anyway.

 I'm not entirely sure; I'm not intimately familiar with how LTO
 streaming works. lto.c's lto_ft_type and lto_ft_common purport to
 recreate TYPE_{POINTER,REFERENCE}_TO, but I don't immediately see how
 that's supposed to work.  I can imagine that we ought to be able to
 recreate those fields after reading everything in, and that's why don't
 stream them; I just don't know where that's done.

Yes, we're re-creating them to avoid streaming all pointer types that might
be unused before streaming.

One nit:

+struct GTY(()) tree_type_non_common {
+  struct tree_type_with_lang_specific common;

shouldn't that field be named w_lang_specific or something like that,
instead of re-using common?

Richard.

 -Nathan



Re: [PATCH] split tree_type, a.k.a. tuplifying types

2011-05-11 Thread Jason Merrill

I'm checking this in to fix build with --enable-gather-detailed-mem-stats.

Jason

commit 091ac850cf8830722c9bae83232f0d95ccd45b2a
Author: Jason Merrill ja...@redhat.com
Date:   Wed May 11 21:36:09 2011 -0400

* tree.c (type_hash_canon): Use struct tree_type_non_common.

diff --git a/gcc/tree.c b/gcc/tree.c
index c38d24b..3357d84 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -6217,7 +6217,7 @@ type_hash_canon (unsigned int hashcode, tree type)
 #ifdef GATHER_STATISTICS
   tree_code_counts[(int) TREE_CODE (type)]--;
   tree_node_counts[(int) t_kind]--;
-  tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type);
+  tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type_non_common);
 #endif
   return t1;
 }


[PATCH] split tree_type, a.k.a. tuplifying types

2011-05-10 Thread Nathan Froyd
tree_type is a fairly big structure, and several of its fields are
overloaded.  This means we waste some space, depending on the type, and
it's also somewhat confusing as to who uses what.

The patch below implements the first step towards tuplifying types:
those pieces which all types use have been split out into a
tree_type_common structure and those pieces which are overloaded live in
a tree_type_non_common structure.  I choose to implement the
lang-specific bit as a separate substructure, on the off-chance that
some types are fortunate enough to not have langage-specific data
attached to them by the FEs--I have not gone through and made a detailed
check of this, but a skimming shows that nearly every interesting type
that we'd care about shrinking has TYPE_LANG_SPECIFIC set on it by some
FE.

There are several miscellaneous places that need to be fixed up after
the removal of tree_type.  The changes to the Ada, Java, ObjC/C++, and
C++ FEs mainly have to do with direct access to the fields of tree_type,
rather than going through accessor macros.  ggc-page.c creates a bucket
size for sizeof (struct tree_type); I changed it to use 'struct
tree_type_non_common' instead.  There are a couple of places in the
compiler where fields are accessed directly--stor-layout.c and
lto/lto.c--I chose to leave those alone.

After this reorganization, the most that we can shrink most types will
be 2-3 words (possibly more, if we moved TYPE_SIZE around so not all
types needed it).  According to PR 45375, the types on which we should
focus are:

- RECORD_TYPE
- FUNCTION_TYPE
- METHOD_TYPE
- POINTER_TYPE
- INTEGER_TYPE
- REFERENCE_TYPE

RECORD_TYPE is not straightforwardly shrinkable.  FUNCTION_TYPE and
METHOD_TYPE could probably be shrunk by a word or two; likewise for
POINTER_TYPE and REFERENCE_TYPE.  (POINTER_TYPE and REFERENCE_TYPE could
also be made smaller by not allocating an entire TREE_VEC for the one
cached value they put in TYPE_CACHED_VALUES...)  INTEGER_TYPE's binfo
field is used by Ada; INTEGER_TYPE could be shrunk by one word were it
not for this overloading.

Other types can of course be shrunk, but the memory savings from doing
so will be negligible

This patch also opens up the possibility of using language-specific
trees for types as well as decls; the C++ FE's tree_size langhook makes
an attempt to do this, but we never call the tree_size langhook for
types.

I haven't included the refactoring of types yet; I'll let this patch sit
on trunk for a couple of days before trying that.

Testing with all languages in progress on x86_64-unknown-linux-gnu;
ObjC/Go/Ada tests have completed with no regressions; C/C++/Fortran are
looking good as well.  OK to commit?

-Nathan

gcc/ada/
* gcc-interface/ada-tree.h (TYPE_OBJECT_RECORD_TYPE): Use TYPE_MINVAL.
(TYPE_GCC_MIN_VALUE): Use TYPE_MINVAL.
(TYPE_GCC_MAX_VALUE): Use TYPE_MAXVAL.

gcc/cp/
* cp-tree.h (TYPENAME_TYPE_FULLNAME, TYPEOF_TYPE_EXPR): Use
TYPE_VALUES_RAW.
(UNDERLYING_TYPE_TYPE, DECLTYPE_TYPE_EXPR): Likewise.
(DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P): Likewise.
(TEMPLATE_TYPE_PARM_INDEX): Likewise.

gcc/
* ggc-page.c (extra_order_size_table): Use struct
tree_type_non_common.
* lto-streamer-in.c (unpack_ts_type_value_fields): Rename to...
(unpack_ts_type_common_value_fields): ...this.  Update comment.
(unpack_value_fields): Adjust for renaming.
(lto_input_ts_type_tree_pointers): Split into...
(lto_input_ts_type_common_tree_pointer): ...this and...
(lto_input_ts_type_non_common_tree_pointers): ...this.
(lto_input_tree_pointers): Adjust for above split.
* lto-streamer-out.c (pack_ts_type_value_fields): Rename to...
(pack_ts_type_common_value_fields): ...this.  Update comment.
(lto_output_ts_type_tree_pointers): Split into...
(lto_output_ts_type_common_tree_pointers): ...this and...
(lto_output_ts_type_non_common_tree_pointers): ...this.
(lto_output_tree_pointers): Adjust for above split.
* lto-streamer.c (check_handled_ts_structures): Mark TS_TYPE_COMMON,
TS_TYPE_WITH_LANG_SPECIFIC, and TS_TYPE_NON_COMMON as handled.
* stor-layout.c (vector_type_mode): Adjust location of mode field.
* tree.h (MARK_TS_TYPE_COMMON, MARK_TS_TYPE_WITH_LANG_SPECIFIC):
Define.
(struct tree_type): Split into...
(struct tree_type_common: ...this and...
(struct tree_type_with_lang_specific): ...this and...
(struct tree_type_non_common): ...this.  Adjust accessor macros
accordingly.
(TYPE_VALUES_RAW): Define.
(union tree_node): Update for above changes.
* tree.c (tree_node_structure_for_code) [tcc_type]: Return
TS_TYPE_NON_COMMON.
(initialize_tree_contains_struct) [TS_TYPE]: Use TS_TYPE_COMMON.
Add TS_TYPE_WITH_LANG_SPECIFIC and TS_TYPE_NON_COMMON.
(tree_code_size) 

Re: [PATCH] split tree_type, a.k.a. tuplifying types

2011-05-10 Thread Mike Stump
On May 10, 2011, at 9:15 AM, Nathan Froyd froy...@codesourcery.com wrote:
 The patch below implements the first step towards tuplifying types:

 OK to commit?

Ok for Objective parts...
 


Re: [PATCH] split tree_type, a.k.a. tuplifying types

2011-05-10 Thread Diego Novillo
On Tue, May 10, 2011 at 13:15, Nathan Froyd froy...@codesourcery.com wrote:

 Other types can of course be shrunk, but the memory savings from doing
 so will be negligible

Have you done any measurements on the potential savings?


 +static void
 +lto_input_ts_type_common_tree_pointers (struct lto_input_block *ib,
 +                                       struct data_in *data_in, tree expr)
 +{
 +  TYPE_SIZE (expr) = lto_input_tree (ib, data_in);
 +  TYPE_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
 +  TYPE_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
 +  TYPE_NAME (expr) = lto_input_tree (ib, data_in);
 +  /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO.  */

Add some wording as to why not?  This was copied from existing
comments, but I do not remember why we were doing this.  Not too
critical, anyway.

OK, otherwise.  Thanks for doing this!


Diego.


Re: [PATCH] split tree_type, a.k.a. tuplifying types

2011-05-10 Thread Tom Tromey
 Nathan == Nathan Froyd froy...@codesourcery.com writes:

Nathan gcc/java/
Nathan * java-tree.h (TYPE_ARGUMENT_SIGNATURE): Use TYPE_MINVAL.

This is ok.

Tom


Re: [PATCH] split tree_type, a.k.a. tuplifying types

2011-05-10 Thread Michael Matz
Hi,

On Tue, 10 May 2011, Nathan Froyd wrote:

   +  /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO.  */
  
  Add some wording as to why not?  This was copied from existing
  comments, but I do not remember why we were doing this.  Not too
  critical, anyway.
 
 I'm not entirely sure; I'm not intimately familiar with how LTO
 streaming works. lto.c's lto_ft_type and lto_ft_common purport to
 recreate TYPE_{POINTER,REFERENCE}_TO, but I don't immediately see how
 that's supposed to work.  I can imagine that we ought to be able to
 recreate those fields after reading everything in, and that's why don't
 stream them; I just don't know where that's done.

That is correct.  As soon as we read in a POINTER_TYPE or REFERENCE_TYPE 
we'll reconstruct the target type's TYPE_{POINTER,REFERENCE}_TO fields as 
being the trees we just process.  Type merging would have to overwrite 
them anyway, so it actually saves time and space to not stream or 
reconstruct them, just to have them overwritten during type merging.


Ciao,
Michael.