public inbox for java-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [4.7 PATCH 00/18] slim down a number of tree nodes
@ 2011-03-11  4:23 Nathan Froyd
  2011-03-11  4:24 ` [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more Nathan Froyd
                   ` (5 more replies)
  0 siblings, 6 replies; 20+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:23 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd, fortran, java-patches

This patch series does something similar to what:

http://gcc.gnu.org/ml/gcc-patches/2010-11/msg02491.html

did, only it does it in a cleaner way and it addresses the problem more
generally.  It introduces a separate substructure (base class) for tree
nodes that include TREE_TYPE so that a tree node can use TREE_TYPE
without having to deal with TREE_CHAIN.  It then goes about making
changes where necessary to both use this new substructure and eliminate
unnecessary TREE_CHAIN usage.

Eliminating the block field from tree_exp would be another nice-to-have
for 4.7, but that's not on my radar of things to address at the moment.
(Matz, you want to do that? :)  Eliminating TREE_TYPE from tree_exp as
suggested on the wiki would be another interesting project, but not one
I plan on tackling.

The patch series touches every front-end in various places.  I have CC'd
the appropriate mailing lists with this introductory email, but I will
only CC those mailing lists on followup patches that touch the
appropriate FE.

I have not rigorously measured memory savings with this patch.  Based on
a (very small) sample, this patch saves ~5% of tree memory according to
dump_tree_statistics...though the amount of tree memory as reported by
dump_tree_statistics is somewhat suspect, since it doesn't include
statistics from copy_node_stat.

The patch series has been bootstrapped on x86_64-unknown-linux-gnu, both
in its entirety and with sub-patches along the way.  Indeed, the patches
were not developed in this order; the checking bits were introduced
first, then any bootstrap or testsuite failures were fixed up, then the
patches were committed in the proper order.

Nathan Froyd (18):
  add typed_tree structure
  enforce TREE_CHAIN and TREE_TYPE accesses
  remove TREE_CHAIN from *_CST nodes
  remove TREE_CHAIN from SSA_NAME nodes
  remove TREE_CHAIN from CONSTRUCTOR nodes
  define CASE_CHAIN accessor for CASE_LABEL_EXPR
  generalize build_case_label to the rest of the compiler
  convert cp *FOR_STMTs to use private scope fields
  convert cp IF_STMTs to use private scope fields
  convert cp SWITCH_STMTs to use private scope fields
  mark EXPR_PACK_EXPANSION as typed only
  make CASE_LABEL_EXPR not abuse TREE_CHAIN
  move TS_EXP to be a substructure of TS_TYPED
  move TS_STATEMENT_LIST to be a substructure of TS_TYPED
  move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier
  make TS_IDENTIFIER be a substructure of TS_BASE
  introduce block_chainon and use BLOCK_CHAIN more
  make TS_BLOCK a substructure of TS_BASE

 gcc/ada/gcc-interface/ada-tree.h |    2 +-
 gcc/ada/gcc-interface/misc.c     |   16 ++++++
 gcc/ada/gcc-interface/trans.c    |    5 +-
 gcc/ada/gcc-interface/utils.c    |    4 +-
 gcc/c-decl.c                     |    8 ++-
 gcc/c-family/c-common.c          |   14 +++++-
 gcc/c-family/c-common.h          |   20 +++++---
 gcc/c-family/c-semantics.c       |   28 ++++-------
 gcc/c-lang.c                     |    2 +
 gcc/c-parser.c                   |    2 +-
 gcc/c-typeck.c                   |    2 +-
 gcc/cp/cp-lang.c                 |   22 +--------
 gcc/cp/cp-objcp-common.c         |   74 +++++++++++++++++++++++++++
 gcc/cp/cp-objcp-common.h         |    1 +
 gcc/cp/cp-tree.def               |   19 ++++---
 gcc/cp/cp-tree.h                 |   43 ++++++++++------
 gcc/cp/decl.c                    |   28 ++++++----
 gcc/cp/decl2.c                   |   20 ++++---
 gcc/cp/error.c                   |    2 +-
 gcc/cp/init.c                    |    6 +-
 gcc/cp/mangle.c                  |   28 +++++++---
 gcc/cp/name-lookup.c             |   10 ++--
 gcc/cp/pt.c                      |   40 +++++++++------
 gcc/cp/repo.c                    |    2 +-
 gcc/cp/rtti.c                    |    6 +-
 gcc/cp/search.c                  |    4 +-
 gcc/cp/semantics.c               |   41 +++++++++------
 gcc/cp/typeck.c                  |    4 +-
 gcc/except.c                     |    5 +-
 gcc/fortran/f95-lang.c           |    8 ++--
 gcc/fortran/trans-decl.c         |    2 +-
 gcc/fortran/trans-io.c           |    2 +-
 gcc/fortran/trans-stmt.c         |   14 ++---
 gcc/function.c                   |   28 ++++++++++
 gcc/function.h                   |    1 +
 gcc/gimplify.c                   |   14 +++---
 gcc/go/go-lang.c                 |    2 +-
 gcc/java/decl.c                  |   13 ++---
 gcc/java/expr.c                  |    9 ++--
 gcc/java/java-tree.h             |    2 +-
 gcc/lto-streamer-in.c            |    2 +-
 gcc/lto-streamer-out.c           |    2 +-
 gcc/lto-streamer.c               |    1 +
 gcc/lto/lto-tree.h               |    2 +-
 gcc/lto/lto.c                    |    3 +-
 gcc/objc/objc-act.c              |   18 +++++++
 gcc/objc/objc-act.h              |    1 +
 gcc/objc/objc-lang.c             |   32 +-----------
 gcc/objcp/objcp-lang.c           |   48 +-----------------
 gcc/omp-low.c                    |    7 +--
 gcc/print-tree.c                 |   11 +---
 gcc/tree-cfg.c                   |   12 ++--
 gcc/tree-eh.c                    |   22 +++-----
 gcc/tree-flow.h                  |    2 +-
 gcc/tree-inline.c                |    3 +-
 gcc/tree-iterator.c              |   17 ++----
 gcc/tree-ssanames.c              |   28 +++-------
 gcc/tree.c                       |   96 ++++++++++++-----------------------
 gcc/tree.def                     |    2 +-
 gcc/tree.h                       |  103 +++++++++++++++++++++++++++++--------
 gcc/treestruct.def               |    1 +
 gcc/varasm.c                     |    1 -
 62 files changed, 535 insertions(+), 432 deletions(-)

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

* [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
@ 2011-03-11  4:24 ` Nathan Froyd
  2011-03-11 13:15   ` Richard Guenther
                     ` (2 more replies)
  2011-03-11  4:30 ` [PATCH 07/18] generalize build_case_label to the rest of the compiler Nathan Froyd
                   ` (4 subsequent siblings)
  5 siblings, 3 replies; 20+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd, fortran, java-patches

BLOCKs have a TREE_CHAIN and a TREE_TYPE; TREE_TYPE is useless for
blocks, but we can't remove TREE_TYPE without also removing TREE_CHAIN.
This patch lays the groundwork to do just that.  It changes places that
use chainon on BLOCKs to use block_chainon, which works identically to
chainon except it uses BLOCK_CHAIN.  And it fixes up a few places that
used TREE_CHAIN when they meant BLOCK_CHAIN.

-Nathan

gcc/ada/
	* gcc-interface/utils.c (gnat_poplevel): Use block_chainon.

gcc/
	* function.h (block_chainon): Declare.
	* function.c (block_chainon): Define.

gcc/cp/
	* decl.c (poplevel): Use block_chainon.

gcc/fortran/
	* f95-lang.c (poplevel): Use BLOCK_CHAIN and block_chainon.

gcc/java/
	* decl.c (poplevel): Use BLOCK_CHAIN and block_chainon.

diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index eac87e0..dd06ca3 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -395,8 +395,8 @@ gnat_poplevel (void)
   else if (BLOCK_VARS (block) == NULL_TREE)
     {
       BLOCK_SUBBLOCKS (level->chain->block)
-	= chainon (BLOCK_SUBBLOCKS (block),
-		   BLOCK_SUBBLOCKS (level->chain->block));
+	= block_chainon (BLOCK_SUBBLOCKS (block),
+			 BLOCK_SUBBLOCKS (level->chain->block));
       BLOCK_CHAIN (block) = free_block_chain;
       free_block_chain = block;
     }
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a0ef39f..de96ac2 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -794,7 +794,7 @@ poplevel (int keep, int reverse, int functionbody)
     }
   else if (block)
     current_binding_level->blocks
-      = chainon (current_binding_level->blocks, block);
+      = block_chainon (current_binding_level->blocks, block);
 
   /* If we did not make a block for the level just exited,
      any blocks made for inner levels
@@ -803,7 +803,7 @@ poplevel (int keep, int reverse, int functionbody)
      of something else.  */
   else if (subblocks)
     current_binding_level->blocks
-      = chainon (current_binding_level->blocks, subblocks);
+      = block_chainon (current_binding_level->blocks, subblocks);
 
   /* Each and every BLOCK node created here in `poplevel' is important
      (e.g. for proper debugging information) so if we created one
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 687f60b..aebe397 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -444,7 +444,7 @@ poplevel (int keep, int reverse, int functionbody)
 
   /* Record the BLOCK node just built as the subblock its enclosing scope.  */
   for (subblock_node = subblock_chain; subblock_node;
-       subblock_node = TREE_CHAIN (subblock_node))
+       subblock_node = BLOCK_CHAIN (subblock_node))
     BLOCK_SUPERCONTEXT (subblock_node) = block_node;
 
   /* Clear out the meanings of the local variables of this level.  */
@@ -475,7 +475,7 @@ poplevel (int keep, int reverse, int functionbody)
   else if (block_node)
     {
       current_binding_level->blocks
-	= chainon (current_binding_level->blocks, block_node);
+	= block_chainon (current_binding_level->blocks, block_node);
     }
 
   /* If we did not make a block for the level just exited, any blocks made for
@@ -484,7 +484,7 @@ poplevel (int keep, int reverse, int functionbody)
      else.  */
   else if (subblock_chain)
     current_binding_level->blocks
-      = chainon (current_binding_level->blocks, subblock_chain);
+      = block_chainon (current_binding_level->blocks, subblock_chain);
   if (block_node)
     TREE_USED (block_node) = 1;
 
diff --git a/gcc/function.c b/gcc/function.c
index 3f721fb..094cf74 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -4167,6 +4167,34 @@ blocks_nreverse (tree t)
   return prev;
 }
 
+/* Concatenate two chains of blocks (chained through BLOCK_CHAIN)
+   by modifying the last node in chain 1 to point to chain 2.  */
+
+tree
+block_chainon (tree op1, tree op2)
+{
+  tree t1;
+
+  if (!op1)
+    return op2;
+  if (!op2)
+    return op1;
+
+  for (t1 = op1; BLOCK_CHAIN (t1); t1 = BLOCK_CHAIN (t1))
+    continue;
+  BLOCK_CHAIN (t1) = op2;
+
+#ifdef ENABLE_TREE_CHECKING
+  {
+    tree t2;
+    for (t2 = op2; t2; t2 = BLOCK_CHAIN (t2))
+      gcc_assert (t2 != t1);
+  }
+#endif
+
+  return op1;
+}
+
 /* Count the subblocks of the list starting with BLOCK.  If VECTOR is
    non-NULL, list them all into VECTOR, in a depth-first preorder
    traversal of the block tree.  Also clear TREE_ASM_WRITTEN in all
diff --git a/gcc/function.h b/gcc/function.h
index 6e7f539..73af294 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -713,6 +713,7 @@ extern void number_blocks (tree);
 
 extern void clear_block_marks (tree);
 extern tree blocks_nreverse (tree);
+extern tree block_chainon (tree, tree);
 
 /* Return size needed for stack frame based on slots so far allocated.
    This size counts from zero.  It is not rounded to STACK_BOUNDARY;
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index a17b826..6e94dff 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -1481,7 +1481,7 @@ poplevel (int keep, int reverse, int functionbody)
 
   /* In each subblock, record that this is its superior.  */
 
-  for (link = subblocks; link; link = TREE_CHAIN (link))
+  for (link = subblocks; link; link = BLOCK_CHAIN (link))
     BLOCK_SUPERCONTEXT (link) = block;
 
   /* Clear out the meanings of the local variables of this level.  */
@@ -1545,7 +1545,7 @@ poplevel (int keep, int reverse, int functionbody)
       if (block)
 	{
 	  current_binding_level->blocks
-	    = chainon (current_binding_level->blocks, block);
+	    = block_chainon (current_binding_level->blocks, block);
 	}
       /* If we did not make a block for the level just exited,
 	 any blocks made for inner levels
@@ -1554,7 +1554,7 @@ poplevel (int keep, int reverse, int functionbody)
 	 of something else.  */
       else if (subblocks)
 	current_binding_level->blocks
-	  = chainon (current_binding_level->blocks, subblocks);
+	  = block_chainon (current_binding_level->blocks, subblocks);
 
       if (bind)
 	java_add_stmt (bind);
-- 
1.7.0.4

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

* [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
  2011-03-11  4:24 ` [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more Nathan Froyd
  2011-03-11  4:30 ` [PATCH 07/18] generalize build_case_label to the rest of the compiler Nathan Froyd
@ 2011-03-11  4:30 ` Nathan Froyd
  2011-03-11  8:12   ` Mike Stump
                     ` (3 more replies)
  2011-03-11  8:18 ` [4.7 PATCH 00/18] slim down a number of tree nodes Mike Stump
                   ` (2 subsequent siblings)
  5 siblings, 4 replies; 20+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:30 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd, fortran, java-patches

Now that we have a structure where not every node might include
TREE_CHAIN or TREE_TYPE, we need to make sure that when we call said
accessors that the argument is properly typed.  This requires a number
of changes:

- It's not enough for FEs to assume that FE-specific DECLs are the only
  tree that needs to be marked specially; we need to mark things as
  TS_TYPED or TS_COMMON.

- To facilitate doing so, move the MARK_* macros for initializing
  tree_contains_struct to tree.h so they are accessible to FEs.

- Additionally, rearrange *_init_ts methods for the C-family languages
  so that we can share code where code needs to be shared.

- Finally, various places need to check for TS_COMMON structure before
  blindly calling TREE_CHAIN.

-Nathan

gcc/ada/
	* gcc-interface/ada-tree.h (union lang_tree_node): Check for
	TS_COMMON before calling TREE_CHAIN.
	* gcc-interface/misc.c (gnat_init_ts): New function.
	(LANG_HOOKS_INIT_TS): Define.

gcc/
	* c-decl.c (union lang_tree_node): Check for TS_COMMON before
	calling TREE_CHAIN.
	* print-tree.c (print_node): Likewise.
	* tree-inline.c (copy_tree_r): Likewise.
	* c-lang.c (LANG_HOOKS_INIT_TS): Define.
	* lto-streamer-in.c (lto_input_tree_pointers): Check for TS_TYPED
	instead of TS_COMMON.
	* lto-streamer-out.c (lto_output_tree_pointers): Likewise.
	* tree.c (initialize_tree_contains_struct): Handle TS_TYPED.
	(copy_node_stat): Zero TREE_CHAIN only if necessary.
	(MARK_TS_BASE, MARK_TS_TYPED, MARK_TS_COMMON): Move these...
	(MARK_TS_DECL_COMMON, MARK_TS_DECL_COMMON, MARK_TS_DECL_WRTL):
	...and these...
	(MARK_TS_DECL_WITH_VIS, MARK_TS_DECL_NON_COMMON): ...and these...
	* tree.h: ...here.
	(TREE_CHAIN): Check for a TS_COMMON structure.
	(TREE_TYPE): Check for a TS_TYPED structure.

gcc/c-family/
	* c-common.h (c_common_init_ts): Declare.
	* c-common.c (c_common_init_ts): Define.

gcc/cp/
	* cp-lang.c (cp_init_ts): Call cp_common_init_ts.  Move
	tree_contains_struct initialization to...
	* cp-objcp-common.c (cp_common_init_ts): ...here.  Use MARK_*
	macros.
	* cp-objcp-common.h (cp_common_init_ts): Declare.
	* cp-tree.h (union lang_tree_node): Check for TS_COMMON before
	calling TREE_CHAIN.

gcc/fortran/
	* f95-lang.c (union lang_tree_node): Check for TS_COMMON before
	calling TREE_CHAIN.

gcc/go/
	* go-lang.c (union lang_tree_node): Check for TS_COMMON before
	calling TREE_CHAIN.

gcc/java/
	* java-tree.h (union lang_tree_node): Check for TS_COMMON before
	calling TREE_CHAIN.

gcc/lto/
	* lto-tree.h (union lang_tree_node): Check for TS_COMMON before
	calling TREE_CHAIN.
	* lto.c (lto_fixup_common): Likewise.

gcc/objc/
	* objc-lang.c (objc_init_ts): Move code for this function...
	* objc-act.c (objc_common_init_ts): ...here. Define.
	* objc-act.h (objc_common_init_ts): Declare.

gcc/objcp/
	* objcp-lang.c (objcxx_init_ts): Call objc_common_init_ts and
	cp_common_init_ts.

diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h
index 9002fa1..3542349 100644
--- a/gcc/ada/gcc-interface/ada-tree.h
+++ b/gcc/ada/gcc-interface/ada-tree.h
@@ -25,7 +25,7 @@
 
 /* The resulting tree type.  */
 union GTY((desc ("0"),
-	   chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
+	   chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
   lang_tree_node
 {
   union tree_node GTY((tag ("0"),
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 4f7a5e1..89823ca 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -696,6 +696,20 @@ gnat_eh_personality (void)
   return gnat_eh_personality_decl;
 }
 
+/* Initialize language-specific bits of tree_contains_struct.  */
+
+static void
+gnat_init_ts (void)
+{
+  MARK_TS_COMMON (UNCONSTRAINED_ARRAY_TYPE);
+
+  MARK_TS_TYPED (UNCONSTRAINED_ARRAY_REF);
+  MARK_TS_TYPED (LOOP_STMT);
+  MARK_TS_TYPED (STMT_STMT);
+  MARK_TS_TYPED (EXIT_STMT);
+  MARK_TS_TYPED (NULL_EXPR);
+}
+
 /* Definitions for our language-specific hooks.  */
 
 #undef  LANG_HOOKS_NAME
@@ -754,6 +768,8 @@ gnat_eh_personality (void)
 #define LANG_HOOKS_EH_PERSONALITY	gnat_eh_personality
 #undef  LANG_HOOKS_DEEP_UNSHARING
 #define LANG_HOOKS_DEEP_UNSHARING	true
+#undef  LANG_HOOKS_INIT_TS
+#define LANG_HOOKS_INIT_TS		gnat_init_ts
 
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index b438b06..14aef5f 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -242,7 +242,7 @@ extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
 /* The resulting tree type.  */
 
 union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
-       chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) TREE_CHAIN (&%h.generic))")))  lang_tree_node
+       chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))  lang_tree_node
  {
   union tree_node GTY ((tag ("0"),
 			desc ("tree_node_structure (&%h)")))
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index d696b5f..7207335 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -9692,4 +9692,13 @@ keyword_is_decl_specifier (enum rid keyword)
     }
 }
 
+/* Initialize language-specific-bits of tree_contains_struct.  */
+
+void
+c_common_init_ts (void)
+{
+  MARK_TS_TYPED (C_MAYBE_CONST_EXPR);
+  MARK_TS_TYPED (EXCESS_PRECISION_EXPR);
+}
+
 #include "gt-c-family-c-common.h"
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 406def9..7e4f0a1 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -707,6 +707,7 @@ extern tree c_common_fixed_point_type_for_size (unsigned int, unsigned int,
 extern tree c_common_unsigned_type (tree);
 extern tree c_common_signed_type (tree);
 extern tree c_common_signed_or_unsigned_type (int, tree);
+extern void c_common_init_ts (void);
 extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int);
 extern bool decl_with_nonnull_addr_p (const_tree);
 extern tree c_fully_fold (tree, bool, bool *);
diff --git a/gcc/c-lang.c b/gcc/c-lang.c
index 0ca2e7c..ae1b081 100644
--- a/gcc/c-lang.c
+++ b/gcc/c-lang.c
@@ -43,6 +43,8 @@ enum c_language_kind c_language = clk_c;
 #define LANG_HOOKS_NAME "GNU C"
 #undef LANG_HOOKS_INIT
 #define LANG_HOOKS_INIT c_objc_common_init
+#undef LANG_HOOKS_INIT_TS
+#define LANG_HOOKS_INIT_TS c_common_init_ts
 
 /* Each front end provides its own lang hook initializer.  */
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index e5c1c09..6506930 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -100,32 +100,12 @@ objcp_tsubst_copy_and_build (tree t ATTRIBUTE_UNUSED,
   return NULL_TREE;
 }
 
-
 static void
 cp_init_ts (void)
 {
-  tree_contains_struct[NAMESPACE_DECL][TS_DECL_NON_COMMON] = 1;
-  tree_contains_struct[USING_DECL][TS_DECL_NON_COMMON] = 1;
-  tree_contains_struct[TEMPLATE_DECL][TS_DECL_NON_COMMON] = 1;
-
-  tree_contains_struct[NAMESPACE_DECL][TS_DECL_WITH_VIS] = 1;
-  tree_contains_struct[USING_DECL][TS_DECL_WITH_VIS] = 1;
-  tree_contains_struct[TEMPLATE_DECL][TS_DECL_WITH_VIS] = 1;
-
-  tree_contains_struct[NAMESPACE_DECL][TS_DECL_WRTL] = 1;
-  tree_contains_struct[USING_DECL][TS_DECL_WRTL] = 1;
-  tree_contains_struct[TEMPLATE_DECL][TS_DECL_WRTL] = 1;
-
-  tree_contains_struct[NAMESPACE_DECL][TS_DECL_COMMON] = 1;
-  tree_contains_struct[USING_DECL][TS_DECL_COMMON] = 1;
-  tree_contains_struct[TEMPLATE_DECL][TS_DECL_COMMON] = 1;
-
-  tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[USING_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[TEMPLATE_DECL][TS_DECL_MINIMAL] = 1;
+  cp_common_init_ts ();
 
   init_shadowed_var_for_decl ();
-
 }
 
 static const char *
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index f045d29..66d2d27 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -222,5 +222,78 @@ init_shadowed_var_for_decl (void)
 					   tree_decl_map_eq, 0);
 }
 
+void
+cp_common_init_ts (void)
+{
+  MARK_TS_DECL_NON_COMMON (NAMESPACE_DECL);
+  MARK_TS_DECL_NON_COMMON (USING_DECL);
+  MARK_TS_DECL_NON_COMMON (TEMPLATE_DECL);
+
+  MARK_TS_COMMON (TEMPLATE_TEMPLATE_PARM);
+  MARK_TS_COMMON (TEMPLATE_TYPE_PARM);
+  MARK_TS_COMMON (TEMPLATE_PARM_INDEX);
+  MARK_TS_COMMON (OVERLOAD);
+  MARK_TS_COMMON (TEMPLATE_INFO);
+  MARK_TS_COMMON (FOR_STMT);
+  MARK_TS_COMMON (TYPENAME_TYPE);
+  MARK_TS_COMMON (TYPEOF_TYPE);
+  MARK_TS_COMMON (IF_STMT);
+  MARK_TS_COMMON (BASELINK);
+  MARK_TS_COMMON (SWITCH_STMT);
+  MARK_TS_COMMON (TYPE_PACK_EXPANSION);
+  MARK_TS_COMMON (EXPR_PACK_EXPANSION);
+  MARK_TS_COMMON (DECLTYPE_TYPE);
+  MARK_TS_COMMON (BOUND_TEMPLATE_TEMPLATE_PARM);
+  MARK_TS_COMMON (UNBOUND_CLASS_TEMPLATE);
+  MARK_TS_COMMON (RANGE_FOR_STMT);
+
+  MARK_TS_TYPED (AGGR_INIT_EXPR);
+  MARK_TS_TYPED (EXPR_STMT);
+  MARK_TS_TYPED (EH_SPEC_BLOCK);
+  MARK_TS_TYPED (CLEANUP_STMT);
+  MARK_TS_TYPED (SCOPE_REF);
+  MARK_TS_TYPED (CAST_EXPR);
+  MARK_TS_TYPED (NON_DEPENDENT_EXPR);
+  MARK_TS_TYPED (MODOP_EXPR);
+  MARK_TS_TYPED (TRY_BLOCK);
+  MARK_TS_TYPED (THROW_EXPR);
+  MARK_TS_TYPED (HANDLER);
+  MARK_TS_TYPED (REINTERPRET_CAST_EXPR);
+  MARK_TS_TYPED (CONST_CAST_EXPR);
+  MARK_TS_TYPED (STATIC_CAST_EXPR);
+  MARK_TS_TYPED (DYNAMIC_CAST_EXPR);
+  MARK_TS_TYPED (TEMPLATE_ID_EXPR);
+  MARK_TS_TYPED (ARROW_EXPR);
+  MARK_TS_TYPED (SIZEOF_EXPR);
+  MARK_TS_TYPED (ALIGNOF_EXPR);
+  MARK_TS_TYPED (AT_ENCODE_EXPR);
+  MARK_TS_TYPED (UNARY_PLUS_EXPR);
+  MARK_TS_TYPED (TRAIT_EXPR);
+  MARK_TS_TYPED (TYPE_ARGUMENT_PACK);
+  MARK_TS_TYPED (NOEXCEPT_EXPR);
+  MARK_TS_TYPED (NONTYPE_ARGUMENT_PACK);
+  MARK_TS_TYPED (WHILE_STMT);
+  MARK_TS_TYPED (NEW_EXPR);
+  MARK_TS_TYPED (VEC_NEW_EXPR);
+  MARK_TS_TYPED (BREAK_STMT);
+  MARK_TS_TYPED (MEMBER_REF);
+  MARK_TS_TYPED (DOTSTAR_EXPR);
+  MARK_TS_TYPED (DO_STMT);
+  MARK_TS_TYPED (DELETE_EXPR);
+  MARK_TS_TYPED (VEC_DELETE_EXPR);
+  MARK_TS_TYPED (CONTINUE_STMT);
+  MARK_TS_TYPED (TAG_DEFN);
+  MARK_TS_TYPED (PSEUDO_DTOR_EXPR);
+  MARK_TS_TYPED (TYPEID_EXPR);
+  MARK_TS_TYPED (MUST_NOT_THROW_EXPR);
+  MARK_TS_TYPED (STMT_EXPR);
+  MARK_TS_TYPED (OFFSET_REF);
+  MARK_TS_TYPED (OFFSETOF_EXPR);
+  MARK_TS_TYPED (PTRMEM_CST);
+  MARK_TS_TYPED (EMPTY_CLASS_EXPR);
+  MARK_TS_TYPED (VEC_INIT_EXPR);
+  MARK_TS_TYPED (USING_STMT);
+  MARK_TS_TYPED (LAMBDA_EXPR);
+}
 
 #include "gt-cp-cp-objcp-common.h"
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 38da59e..c668ad8 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -28,6 +28,7 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
 					 tree, bool);
 
 extern bool cp_function_decl_explicit_p (tree decl);
+extern void cp_common_init_ts (void);
 
 /* Lang hooks that are shared between C++ and ObjC++ are defined here.  Hooks
    specific to C++ or ObjC++ go in cp/cp-lang.c and objcp/objcp-lang.c,
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 238d0cf..1783915 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -702,7 +702,7 @@ enum cp_tree_node_structure_enum {
 
 /* The resulting tree type.  */
 union GTY((desc ("cp_tree_node_structure (&%h)"),
-       chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)"))) lang_tree_node {
+       chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL"))) lang_tree_node {
   union tree_node GTY ((tag ("TS_CP_GENERIC"),
 			desc ("tree_node_structure (&%h)"))) generic;
   struct template_parm_index_s GTY ((tag ("TS_CP_TPI"))) tpi;
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index a3ac860..687f60b 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -59,7 +59,7 @@ lang_identifier {
 /* The resulting tree type.  */
 
 union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
-     chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
+     chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
 
 lang_tree_node {
   union tree_node GTY((tag ("0"),
diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c
index b59e72d..5132e97 100644
--- a/gcc/go/go-lang.c
+++ b/gcc/go/go-lang.c
@@ -65,7 +65,7 @@ struct GTY(()) lang_identifier
 /* The resulting tree type.  */
 
 union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
-	   chain_next ("(union lang_tree_node *) TREE_CHAIN (&%h.generic)")))
+	   chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
 lang_tree_node
 {
   union tree_node GTY((tag ("0"),
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 3addcca..e422b4a 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -587,7 +587,7 @@ struct GTY(()) lang_identifier {
 
 /* The resulting tree type.  */
 union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
-       chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
+       chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
  
   lang_tree_node {
   union tree_node GTY ((tag ("0"), 
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 7409c1a..45809b8 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -2326,7 +2326,7 @@ lto_input_tree_pointers (struct lto_input_block *ib, struct data_in *data_in,
 
   code = TREE_CODE (expr);
 
-  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
+  if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
     lto_input_ts_common_tree_pointers (ib, data_in, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 29d171b..a4e8b70 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -1169,7 +1169,7 @@ lto_output_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
 
   code = TREE_CODE (expr);
 
-  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
+  if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
     lto_output_ts_common_tree_pointers (ob, expr, ref_p);
 
   if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
diff --git a/gcc/lto/lto-tree.h b/gcc/lto/lto-tree.h
index d187fe2..847348c 100644
--- a/gcc/lto/lto-tree.h
+++ b/gcc/lto/lto-tree.h
@@ -48,7 +48,7 @@ enum lto_tree_node_structure_enum {
 };
 
 union GTY((desc ("lto_tree_node_structure (&%h)"),
-	  chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
+	  chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
     lang_tree_node
 {
   union tree_node GTY ((tag ("TS_LTO_GENERIC"),
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 71c8cdb..78a7977 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -1618,7 +1618,8 @@ lto_fixup_common (tree t, void *data)
 
   /* This is not very efficient because we cannot do tail-recursion with
      a long chain of trees. */
-  LTO_FIXUP_SUBTREE (TREE_CHAIN (t));
+  if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_COMMON))
+    LTO_FIXUP_SUBTREE (TREE_CHAIN (t));
 }
 
 /* Fix up fields of a decl_minimal T.  DATA points to fix-up states.  */
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 049dc00..e5bd52a 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -10541,4 +10541,22 @@ objc_v2_encode_prop_attr (tree property)
   return get_identifier (string);
 }
 
+void
+objc_common_init_ts (void)
+{
+  c_common_init_ts ();
+
+  MARK_TS_DECL_NON_COMMON (CLASS_METHOD_DECL);
+  MARK_TS_DECL_NON_COMMON (INSTANCE_METHOD_DECL);
+  MARK_TS_DECL_NON_COMMON (KEYWORD_DECL);
+  MARK_TS_DECL_NON_COMMON (PROPERTY_DECL);
+
+  MARK_TS_COMMON (CLASS_INTERFACE_TYPE);
+  MARK_TS_COMMON (PROTOCOL_INTERFACE_TYPE);
+  MARK_TS_COMMON (CLASS_IMPLEMENTATION_TYPE);
+
+  MARK_TS_TYPED (MESSAGE_SEND_EXPR);
+  MARK_TS_TYPED (PROPERTY_REF);
+}
+
 #include "gt-objc-objc-act.h"
diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h
index 3983d4b..909181a 100644
--- a/gcc/objc/objc-act.h
+++ b/gcc/objc/objc-act.h
@@ -28,6 +28,7 @@ bool objc_init (void);
 const char *objc_printable_name (tree, int);
 tree objc_fold_obj_type_ref (tree, tree);
 int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
+void objc_common_init_ts (void);
 
 /* NB: The remaining public functions are prototyped in c-common.h, for the
    benefit of stub-objc.c and objc-act.c.  */
diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c
index fd65776..169b894 100644
--- a/gcc/objc/objc-lang.c
+++ b/gcc/objc/objc-lang.c
@@ -36,7 +36,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-lang.h"
 
 enum c_language_kind c_language = clk_objc;
-static void objc_init_ts (void);
 
 /* Lang hooks common to C and ObjC are declared in c-objc-common.h;
    consequently, there should be very few hooks below.  */
@@ -50,7 +49,7 @@ static void objc_init_ts (void);
 #undef LANG_HOOKS_GIMPLIFY_EXPR 
 #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
 #undef LANG_HOOKS_INIT_TS
-#define LANG_HOOKS_INIT_TS objc_init_ts
+#define LANG_HOOKS_INIT_TS objc_common_init_ts
 
 /* Each front end provides its own lang hook initializer.  */
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -58,33 +57,4 @@ struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 /* Lang hook routines common to C and ObjC appear in c-objc-common.c;
    there should be very few (if any) routines below.  */
 
-static void
-objc_init_ts (void)
-{
-  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_NON_COMMON] = 1;
-  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_NON_COMMON] = 1;
-  tree_contains_struct[KEYWORD_DECL][TS_DECL_NON_COMMON] = 1;
-  tree_contains_struct[PROPERTY_DECL][TS_DECL_NON_COMMON] = 1;
-  
-  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_WITH_VIS] = 1;
-  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_WITH_VIS] = 1;
-  tree_contains_struct[KEYWORD_DECL][TS_DECL_WITH_VIS] = 1;
-  tree_contains_struct[PROPERTY_DECL][TS_DECL_WITH_VIS] = 1;
-
-  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_WRTL] = 1;
-  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_WRTL] = 1;
-  tree_contains_struct[KEYWORD_DECL][TS_DECL_WRTL] = 1;
-  tree_contains_struct[PROPERTY_DECL][TS_DECL_WRTL] = 1;
-  
-  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[KEYWORD_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[PROPERTY_DECL][TS_DECL_MINIMAL] = 1;
-  
-  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_COMMON] = 1;
-  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_COMMON] = 1;
-  tree_contains_struct[KEYWORD_DECL][TS_DECL_COMMON] = 1;
-  tree_contains_struct[PROPERTY_DECL][TS_DECL_COMMON] = 1;
-}
-
 #include "gtype-objc.h"
diff --git a/gcc/objcp/objcp-lang.c b/gcc/objcp/objcp-lang.c
index fe2be66..0019022 100644
--- a/gcc/objcp/objcp-lang.c
+++ b/gcc/objcp/objcp-lang.c
@@ -89,52 +89,8 @@ objcp_tsubst_copy_and_build (tree t, tree args, tsubst_flags_t complain,
 static void
 objcxx_init_ts (void)
 {
-  /* objc decls */
-  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_NON_COMMON] = 1;
-  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_NON_COMMON] = 1;
-  tree_contains_struct[KEYWORD_DECL][TS_DECL_NON_COMMON] = 1;
-  tree_contains_struct[PROPERTY_DECL][TS_DECL_NON_COMMON] = 1;
-  
-  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_WITH_VIS] = 1;
-  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_WITH_VIS] = 1;
-  tree_contains_struct[KEYWORD_DECL][TS_DECL_WITH_VIS] = 1;
-  tree_contains_struct[PROPERTY_DECL][TS_DECL_WITH_VIS] = 1;
-
-  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_WRTL] = 1;
-  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_WRTL] = 1;
-  tree_contains_struct[KEYWORD_DECL][TS_DECL_WRTL] = 1;
-  tree_contains_struct[PROPERTY_DECL][TS_DECL_WRTL] = 1;
-  
-  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[KEYWORD_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[PROPERTY_DECL][TS_DECL_MINIMAL] = 1;
-  
-  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_COMMON] = 1;
-  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_COMMON] = 1;
-  tree_contains_struct[KEYWORD_DECL][TS_DECL_COMMON] = 1;
-  tree_contains_struct[PROPERTY_DECL][TS_DECL_COMMON] = 1;
-  
-  /* C++ decls */
-  tree_contains_struct[NAMESPACE_DECL][TS_DECL_NON_COMMON] = 1;
-  tree_contains_struct[USING_DECL][TS_DECL_NON_COMMON] = 1;
-  tree_contains_struct[TEMPLATE_DECL][TS_DECL_NON_COMMON] = 1;
-
-  tree_contains_struct[NAMESPACE_DECL][TS_DECL_WITH_VIS] = 1;
-  tree_contains_struct[USING_DECL][TS_DECL_WITH_VIS] = 1;
-  tree_contains_struct[TEMPLATE_DECL][TS_DECL_WITH_VIS] = 1;
-
-  tree_contains_struct[NAMESPACE_DECL][TS_DECL_WRTL] = 1;
-  tree_contains_struct[USING_DECL][TS_DECL_WRTL] = 1;
-  tree_contains_struct[TEMPLATE_DECL][TS_DECL_WRTL] = 1;
-  
-  tree_contains_struct[NAMESPACE_DECL][TS_DECL_COMMON] = 1;
-  tree_contains_struct[USING_DECL][TS_DECL_COMMON] = 1;
-  tree_contains_struct[TEMPLATE_DECL][TS_DECL_COMMON] = 1;
- 
-  tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[USING_DECL][TS_DECL_MINIMAL] = 1;
-  tree_contains_struct[TEMPLATE_DECL][TS_DECL_MINIMAL] = 1;
+  objc_common_init_ts ();
+  cp_common_init_ts ();
 
   init_shadowed_var_for_decl ();
 }
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index dfd3589..b0c6899 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -756,7 +756,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
 	      print_node (file, temp, TREE_OPERAND (node, i), indent + 4);
 	    }
 	}
-      print_node (file, "chain", TREE_CHAIN (node), indent + 4);
+      if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
+	print_node (file, "chain", TREE_CHAIN (node), indent + 4);
       break;
 
     case tcc_constant:
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index de30cfd..45c7e88 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4295,7 +4295,8 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
 	 here.  */
       tree chain = NULL_TREE, new_tree;
 
-      chain = TREE_CHAIN (*tp);
+      if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
+	chain = TREE_CHAIN (*tp);
 
       /* Copy the node.  */
       new_tree = copy_node (*tp);
diff --git a/gcc/tree.c b/gcc/tree.c
index 798bc08..68f40c9 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -351,53 +351,6 @@ initialize_tree_contains_struct (void)
 {
   unsigned i;
 
-#define MARK_TS_BASE(C)					\
-  do {							\
-    tree_contains_struct[C][TS_BASE] = 1;		\
-  } while (0)
-
-#define MARK_TS_TYPED(C)				\
-  do {							\
-    MARK_TS_BASE (C);					\
-    tree_contains_struct[C][TS_TYPED] = 1;		\
-  } while (0)
-
-#define MARK_TS_COMMON(C)				\
-  do {							\
-    MARK_TS_TYPED (C);					\
-    tree_contains_struct[C][TS_COMMON] = 1;		\
-  } while (0)
-
-#define MARK_TS_DECL_MINIMAL(C)				\
-  do {							\
-    MARK_TS_COMMON (C);					\
-    tree_contains_struct[C][TS_DECL_MINIMAL] = 1;	\
-  } while (0)
-
-#define MARK_TS_DECL_COMMON(C)				\
-  do {							\
-    MARK_TS_DECL_MINIMAL (C);				\
-    tree_contains_struct[C][TS_DECL_COMMON] = 1;	\
-  } while (0)
-
-#define MARK_TS_DECL_WRTL(C)				\
-  do {							\
-    MARK_TS_DECL_COMMON (C);				\
-    tree_contains_struct[C][TS_DECL_WRTL] = 1;		\
-  } while (0)
-
-#define MARK_TS_DECL_WITH_VIS(C)			\
-  do {							\
-    MARK_TS_DECL_WRTL (C);				\
-    tree_contains_struct[C][TS_DECL_WITH_VIS] = 1;	\
-  } while (0)
-
-#define MARK_TS_DECL_NON_COMMON(C)			\
-  do {							\
-    MARK_TS_DECL_WITH_VIS (C);				\
-    tree_contains_struct[C][TS_DECL_NON_COMMON] = 1;	\
-  } while (0)
-
   for (i = ERROR_MARK; i < LAST_AND_UNUSED_TREE_CODE; i++)
     {
       enum tree_code code;
@@ -412,10 +365,14 @@ initialize_tree_contains_struct (void)
       /* Mark all the structures that TS is derived from.  */
       switch (ts_code)
 	{
-	case TS_COMMON:
+	case TS_TYPED:
 	  MARK_TS_BASE (code);
 	  break;
 
+	case TS_COMMON:
+	  MARK_TS_TYPED (code);
+	  break;
+
 	case TS_INT_CST:
 	case TS_REAL_CST:
 	case TS_FIXED_CST:
@@ -521,14 +478,6 @@ initialize_tree_contains_struct (void)
   gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL]);
   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL]);
   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON]);
-
-#undef MARK_TS_BASE
-#undef MARK_TS_COMMON
-#undef MARK_TS_DECL_MINIMAL
-#undef MARK_TS_DECL_COMMON
-#undef MARK_TS_DECL_WRTL
-#undef MARK_TS_DECL_WITH_VIS
-#undef MARK_TS_DECL_NON_COMMON
 }
 
 
@@ -944,7 +893,7 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
 }
 \f
 /* Return a new node with the same contents as NODE except that its
-   TREE_CHAIN is zero and it has a fresh uid.  */
+   TREE_CHAIN, if it has one, is zero and it has a fresh uid.  */
 
 tree
 copy_node_stat (tree node MEM_STAT_DECL)
@@ -959,7 +908,8 @@ copy_node_stat (tree node MEM_STAT_DECL)
   t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
   memcpy (t, node, length);
 
-  TREE_CHAIN (t) = 0;
+  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
+    TREE_CHAIN (t) = 0;
   TREE_ASM_WRITTEN (t) = 0;
   TREE_VISITED (t) = 0;
   if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
diff --git a/gcc/tree.h b/gcc/tree.h
index 2f772e1..4ad2d3e 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -50,6 +50,54 @@ MAX_TREE_CODES
 extern unsigned char tree_contains_struct[MAX_TREE_CODES][64];
 #define CODE_CONTAINS_STRUCT(CODE, STRUCT) (tree_contains_struct[(CODE)][(STRUCT)])
 
+/* Macros for initializing `tree_contains_struct'.  */
+#define MARK_TS_BASE(C)					\
+  do {							\
+    tree_contains_struct[C][TS_BASE] = 1;		\
+  } while (0)
+
+#define MARK_TS_TYPED(C)				\
+  do {							\
+    MARK_TS_BASE (C);					\
+    tree_contains_struct[C][TS_TYPED] = 1;		\
+  } while (0)
+
+#define MARK_TS_COMMON(C)				\
+  do {							\
+    MARK_TS_TYPED (C);					\
+    tree_contains_struct[C][TS_COMMON] = 1;		\
+  } while (0)
+
+#define MARK_TS_DECL_MINIMAL(C)				\
+  do {							\
+    MARK_TS_COMMON (C);					\
+    tree_contains_struct[C][TS_DECL_MINIMAL] = 1;	\
+  } while (0)
+
+#define MARK_TS_DECL_COMMON(C)				\
+  do {							\
+    MARK_TS_DECL_MINIMAL (C);				\
+    tree_contains_struct[C][TS_DECL_COMMON] = 1;	\
+  } while (0)
+
+#define MARK_TS_DECL_WRTL(C)				\
+  do {							\
+    MARK_TS_DECL_COMMON (C);				\
+    tree_contains_struct[C][TS_DECL_WRTL] = 1;		\
+  } while (0)
+
+#define MARK_TS_DECL_WITH_VIS(C)			\
+  do {							\
+    MARK_TS_DECL_WRTL (C);				\
+    tree_contains_struct[C][TS_DECL_WITH_VIS] = 1;	\
+  } while (0)
+
+#define MARK_TS_DECL_NON_COMMON(C)			\
+  do {							\
+    MARK_TS_DECL_WITH_VIS (C);				\
+    tree_contains_struct[C][TS_DECL_NON_COMMON] = 1;	\
+  } while (0)
+
 /* Number of language-independent tree codes.  */
 #define NUM_TREE_CODES ((int) LAST_AND_UNUSED_TREE_CODE)
 
@@ -864,7 +912,7 @@ enum tree_node_structure_enum {
    are chained together.  */
 
 #define TREE_CHAIN(NODE) __extension__ \
-(*({__typeof (NODE) const __t = (NODE);				\
+(*({__typeof (NODE) const __t = CONTAINS_STRUCT_CHECK (NODE, TS_COMMON);\
     &__t->common.chain; }))
 
 /* In all nodes that are expressions, this is the data type of the expression.
@@ -872,7 +920,7 @@ enum tree_node_structure_enum {
    In ARRAY_TYPE nodes, this is the type of the elements.
    In VECTOR_TYPE nodes, this is the type of the elements.  */
 #define TREE_TYPE(NODE) __extension__ \
-(*({__typeof (NODE) const __t = (NODE);					\
+(*({__typeof (NODE) const __t = CONTAINS_STRUCT_CHECK (NODE, TS_TYPED); \
     &__t->typed.type; }))
 
 extern void tree_contains_struct_check_failed (const_tree,
-- 
1.7.0.4

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

* [PATCH 07/18] generalize build_case_label to the rest of the compiler
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
  2011-03-11  4:24 ` [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more Nathan Froyd
@ 2011-03-11  4:30 ` Nathan Froyd
  2011-03-11 13:01   ` Joseph S. Myers
  2011-03-11 14:56   ` Tom Tromey
  2011-03-11  4:30 ` [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses Nathan Froyd
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 20+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:30 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd, fortran, java-patches

If we're going to add another TREE_OPERAND to CASE_LABEL_EXPR, then we'd
have to update a number of calls to buildN or similar to know about the
new operand.  But that's not a good idea; the new operand is a strictly
private thing and FEs in particular shouldn't have to know anything
about it.  Instead, define a build_case_label that accepts the current
three operands CASE_LABEL_EXPR requires; build_case_label can then be
updated later.  (Actually, since it can use CASE_CHAIN, it doesn't have
to be updated at all!)

This patch does lose location information on CASE_LABEL_EXPRs from the C
family of front-ends; it did not seem worth it to have a number of
places pass input_location when said information isn't even used.  I'm
happy to add the location_t argument back to CASE_LABEL_EXPRs if people
think that's worthwhile.

-Nathan

gcc/ada/
	* gcc-interface/trans.c (Case_Statement_to_gnu): Call build_case_label.

gcc/
	* except.c (sjlj_emit_dispatch_table): Call build_case_label.
	* gimplify.c (gimplify_switch_expr): Likewise.
	* omp-low.c (expand_omp_sections): Likewise.
	* tree-eh.c (lower_try_finally_switch): Likewise.
	(lower_eh_dispatch): Likewise.
	* tree.h (build_case_label): Declare.
	* tree.c (build_case_label): Define.

gcc/c-family/
	* c-common.c (c_add_case_label): Omit the loc argument to
	build_case_label.
	* c-common.h (build_case_label): Remove.
	* c-semantics.c (build_case_label): Remove.

gcc/cp/
	* decl.c (finish_case_label): Omit the loc argument to
	build_case_label.

gcc/fortran/
	* trans-decl.c (gfc_trans_entry_master_switch): Call build_case_label.
	* trans-io.c (add_case): Likewise.
	* trans-stmt.c (gfc_trans_integer_select): Likewise.
	(gfc_trans_character_select): Likewise.

gcc/java/
	* expr.c (expand_java_switch): Call build_case_label.
	(expand_java_add_case): Likewise.

diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index e438960..90220f2 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -2047,9 +2047,8 @@ Case_Statement_to_gnu (Node_Id gnat_node)
 	  if ((!gnu_low || TREE_CODE (gnu_low) == INTEGER_CST)
 	      && (!gnu_high || TREE_CODE (gnu_high) == INTEGER_CST))
 	    {
-	      add_stmt_with_node (build3
-				  (CASE_LABEL_EXPR, void_type_node,
-				   gnu_low, gnu_high,
+	      add_stmt_with_node (build_case_label
+				  (gnu_low, gnu_high,
 				   create_artificial_label (input_location)),
 				  gnat_choice);
 	      choices_added_p = true;
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 7207335..da859ec 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -5298,7 +5298,7 @@ c_add_case_label (location_t loc, splay_tree cases, tree cond, tree orig_type,
     }
 
   /* Add a CASE_LABEL to the statement-tree.  */
-  case_label = add_stmt (build_case_label (loc, low_value, high_value, label));
+  case_label = add_stmt (build_case_label (low_value, high_value, label));
   /* Register this case label in the splay tree.  */
   splay_tree_insert (cases,
 		     (splay_tree_key) low_value,
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 7e4f0a1..382d535 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -829,7 +829,6 @@ extern void warn_for_omitted_condop (location_t, tree);
 
 extern tree do_case (location_t, tree, tree);
 extern tree build_stmt (location_t, enum tree_code, ...);
-extern tree build_case_label (location_t, tree, tree, tree);
 extern tree build_real_imag_expr (location_t, enum tree_code, tree);
 
 /* These functions must be defined by each front-end which implements
diff --git a/gcc/c-family/c-semantics.c b/gcc/c-family/c-semantics.c
index 0f9f51e..a5bd9ba 100644
--- a/gcc/c-family/c-semantics.c
+++ b/gcc/c-family/c-semantics.c
@@ -131,15 +131,6 @@ build_stmt (location_t loc, enum tree_code code, ...)
   return ret;
 }
 
-/* Create a CASE_LABEL_EXPR tree node and return it.  */
-
-tree
-build_case_label (location_t loc,
-		  tree low_value, tree high_value, tree label_decl)
-{
-  return build_stmt (loc, CASE_LABEL_EXPR, low_value, high_value, label_decl);
-}
-
 /* Build a REALPART_EXPR or IMAGPART_EXPR, according to CODE, from ARG.  */
 
 tree
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 14d530a..6ff6974 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2933,7 +2933,7 @@ finish_case_label (location_t loc, tree low_value, tree high_value)
       /* For templates, just add the case label; we'll do semantic
 	 analysis at instantiation-time.  */
       label = build_decl (loc, LABEL_DECL, NULL_TREE, NULL_TREE);
-      return add_stmt (build_case_label (loc, low_value, high_value, label));
+      return add_stmt (build_case_label (low_value, high_value, label));
     }
 
   /* Find the condition on which this switch statement depends.  */
diff --git a/gcc/except.c b/gcc/except.c
index 251a550..def8a53 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1288,9 +1288,8 @@ sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch)
 	    tree t_label, case_elt;
 
 	    t_label = create_artificial_label (UNKNOWN_LOCATION);
-	    case_elt = build3 (CASE_LABEL_EXPR, void_type_node,
-			       build_int_cst (NULL, disp_index),
-			       NULL, t_label);
+	    case_elt = build_case_label (build_int_cst (NULL, disp_index),
+					 NULL, t_label);
 	    gimple_switch_set_label (switch_stmt, disp_index, case_elt);
 
 	    label = label_rtx (t_label);
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 08207e0..c6698c5 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -4298,7 +4298,7 @@ gfc_trans_entry_master_switch (gfc_entry_list * el)
       /* Add the case label.  */
       label = gfc_build_label_decl (NULL_TREE);
       val = build_int_cst (gfc_array_index_type, el->id);
-      tmp = build3_v (CASE_LABEL_EXPR, val, NULL_TREE, label);
+      tmp = build_case_label (val, NULL_TREE, label);
       gfc_add_expr_to_block (&block, tmp);
 
       /* And jump to the actual entry point.  */
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index f6a783f..023e0a8 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -838,7 +838,7 @@ add_case (int label_value, gfc_st_label * label, stmtblock_t * body)
   tmp = gfc_build_label_decl (NULL_TREE);
 
   /* And the case itself.  */
-  tmp = build3_v (CASE_LABEL_EXPR, value, NULL_TREE, tmp);
+  tmp = build_case_label (value, NULL_TREE, tmp);
   gfc_add_expr_to_block (body, tmp);
 
   /* Jump to the label.  */
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index e120285..41c2d0e 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -1625,8 +1625,7 @@ gfc_trans_integer_select (gfc_code * code)
 
 	  /* Add this case label.
              Add parameter 'label', make it match GCC backend.  */
-	  tmp = fold_build3_loc (input_location, CASE_LABEL_EXPR,
-				 void_type_node, low, high, label);
+	  tmp = build_case_label (low, high, label);
 	  gfc_add_expr_to_block (&body, tmp);
 	}
 
@@ -1903,8 +1902,7 @@ gfc_trans_character_select (gfc_code *code)
 
 		  /* Add this case label.
 		     Add parameter 'label', make it match GCC backend.  */
-		  tmp = fold_build3_loc (input_location, CASE_LABEL_EXPR,
-					 void_type_node, low, high, label);
+		  tmp = build_case_label (low, high, label);
 		  gfc_add_expr_to_block (&body, tmp);
 		}
 
@@ -1983,11 +1981,9 @@ gfc_trans_character_select (gfc_code *code)
       for (d = c->ext.block.case_list; d; d = d->next)
         {
 	  label = gfc_build_label_decl (NULL_TREE);
-	  tmp = fold_build3_loc (input_location, CASE_LABEL_EXPR,
-				 void_type_node,
-				 (d->low == NULL && d->high == NULL)
-				 ? NULL : build_int_cst (NULL_TREE, d->n),
-				 NULL, label);
+	  tmp = build_case_label ((d->low == NULL && d->high == NULL)
+				  ? NULL : build_int_cst (NULL_TREE, d->n),
+				  NULL, label);
           gfc_add_expr_to_block (&body, tmp);
         }
 
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 350d793..89e647d 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1582,10 +1582,11 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
 			break;
 		    }
 		  if (i == len)
-		    default_case = build3 (CASE_LABEL_EXPR, void_type_node,
-					   NULL_TREE, NULL_TREE,
-					   CASE_LABEL (VEC_index (tree,
-								  labels, 0)));
+		    {
+		      tree label = CASE_LABEL (VEC_index (tree, labels, 0));
+		      default_case = build_case_label (NULL_TREE, NULL_TREE,
+						       label);
+		    }
 		}
 	    }
 
@@ -1594,9 +1595,8 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
 	      gimple new_default;
 
 	      default_case
-		= build3 (CASE_LABEL_EXPR, void_type_node,
-			  NULL_TREE, NULL_TREE,
-			  create_artificial_label (UNKNOWN_LOCATION));
+		= build_case_label (NULL_TREE, NULL_TREE,
+				    create_artificial_label (UNKNOWN_LOCATION));
 	      new_default = gimple_build_label (CASE_LABEL (default_case));
 	      gimplify_seq_add_stmt (&switch_body_seq, new_default);
 	    }
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 53feab5..3be1cff 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -1874,8 +1874,8 @@ expand_java_switch (tree selector, int default_pc)
 			NULL_TREE, NULL_TREE);
   java_add_stmt (switch_expr);
 
-  x = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE,
-	      create_artificial_label (input_location));
+  x = build_case_label (NULL_TREE, NULL_TREE,
+			create_artificial_label (input_location));
   append_to_statement_list (x, &SWITCH_BODY (switch_expr));
 
   x = build1 (GOTO_EXPR, void_type_node, lookup_label (default_pc));
@@ -1891,8 +1891,8 @@ expand_java_add_case (tree switch_expr, int match, int target_pc)
 
   value = build_int_cst (TREE_TYPE (switch_expr), match);
   
-  x = build3 (CASE_LABEL_EXPR, void_type_node, value, NULL_TREE,
-	      create_artificial_label (input_location));
+  x = build_case_label (value, NULL_TREE,
+			create_artificial_label (input_location));
   append_to_statement_list (x, &SWITCH_BODY (switch_expr));
 
   x = build1 (GOTO_EXPR, void_type_node, lookup_label (target_pc));
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index c3f2178..13af7fc 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -4773,8 +4773,7 @@ expand_omp_sections (struct omp_region *region)
   i = 0;
   if (exit_reachable)
     {
-      t = build3 (CASE_LABEL_EXPR, void_type_node,
-		  build_int_cst (unsigned_type_node, 0), NULL, l2);
+      t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
       VEC_quick_push (tree, label_vec, t);
       i++;
     }
@@ -4799,7 +4798,7 @@ expand_omp_sections (struct omp_region *region)
 
       t = gimple_block_label (s_entry_bb);
       u = build_int_cst (unsigned_type_node, casei);
-      u = build3 (CASE_LABEL_EXPR, void_type_node, u, NULL, t);
+      u = build_case_label (u, NULL, t);
       VEC_quick_push (tree, label_vec, u);
 
       si = gsi_last_bb (s_entry_bb);
@@ -4820,7 +4819,7 @@ expand_omp_sections (struct omp_region *region)
 
   /* Error handling code goes in DEFAULT_BB.  */
   t = gimple_block_label (default_bb);
-  u = build3 (CASE_LABEL_EXPR, void_type_node, NULL, NULL, t);
+  u = build_case_label (NULL, NULL, t);
   make_edge (l0_bb, default_bb, 0);
 
   stmt = gimple_build_switch_vec (vmain, u, label_vec);
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index f189b9b..a09e6a6 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -1337,9 +1337,8 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
 			       build_int_cst (NULL, fallthru_index));
       gimple_seq_add_stmt (&tf->top_p_seq, x);
 
-      last_case = build3 (CASE_LABEL_EXPR, void_type_node,
-			  build_int_cst (NULL, fallthru_index),
-			  NULL, create_artificial_label (tf_loc));
+      last_case = build_case_label (build_int_cst (NULL, fallthru_index),
+				    NULL, create_artificial_label (tf_loc));
       VEC_quick_push (tree, case_label_vec, last_case);
       last_case_index++;
 
@@ -1362,9 +1361,8 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
       x = gimple_build_goto (finally_label);
       gimple_seq_add_stmt (&eh_seq, x);
 
-      last_case = build3 (CASE_LABEL_EXPR, void_type_node,
-			  build_int_cst (NULL, eh_index),
-			  NULL, create_artificial_label (tf_loc));
+      last_case = build_case_label (build_int_cst (NULL, eh_index),
+				    NULL, create_artificial_label (tf_loc));
       VEC_quick_push (tree, case_label_vec, last_case);
       last_case_index++;
 
@@ -1415,9 +1413,8 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
         {
           tree case_lab;
           void **slot;
-          case_lab = build3 (CASE_LABEL_EXPR, void_type_node,
-                             build_int_cst (NULL, switch_id),
-			     NULL, NULL);
+          case_lab = build_case_label (build_int_cst (NULL, switch_id),
+				       NULL, NULL);
           /* We store the cont_stmt in the pointer map, so that we can recover
              it in the loop below.  We don't create the new label while
              walking the goto_queue because pointers don't offer a stable
@@ -3136,8 +3133,8 @@ lower_eh_dispatch (basic_block src, gimple stmt)
 		   blocks at the end of this pass.  */
 		if (! pointer_set_contains (seen_values, TREE_VALUE (flt_node)))
 		  {
-		    tree t = build3 (CASE_LABEL_EXPR, void_type_node,
-				     TREE_VALUE (flt_node), NULL, lab);
+		    tree t = build_case_label (TREE_VALUE (flt_node),
+					       NULL, lab);
 		    VEC_safe_push (tree, heap, labels, t);
 		    pointer_set_insert (seen_values, TREE_VALUE (flt_node));
 		    have_label = true;
@@ -3184,8 +3181,7 @@ lower_eh_dispatch (basic_block src, gimple stmt)
 	    gsi_insert_before (&gsi, x, GSI_SAME_STMT);
 
 	    /* Turn the default label into a default case.  */
-	    default_label = build3 (CASE_LABEL_EXPR, void_type_node,
-				    NULL, NULL, default_label);
+	    default_label = build_case_label (NULL, NULL, default_label);
 	    sort_case_labels (labels);
 
 	    x = gimple_build_switch_vec (filter, default_label, labels);
diff --git a/gcc/tree.c b/gcc/tree.c
index da16641..d63e7d5 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1629,6 +1629,23 @@ make_tree_binfo_stat (unsigned base_binfos MEM_STAT_DECL)
   return t;
 }
 
+/* Create a CASE_LABEL_EXPR tree node and return it.  */
+
+tree
+build_case_label (tree low_value, tree high_value, tree label_decl)
+{
+  tree t = make_node (CASE_LABEL_EXPR);
+
+  TREE_TYPE (t) = void_type_node;
+  SET_EXPR_LOCATION (t, input_location);
+
+  CASE_LOW (t) = low_value;
+  CASE_HIGH (t) = high_value;
+  CASE_LABEL (t) = label_decl;
+  CASE_CHAIN (t) = NULL_TREE;
+
+  return t;
+}
 
 /* Build a newly constructed TREE_VEC node of length LEN.  */
 
diff --git a/gcc/tree.h b/gcc/tree.h
index 58b3b9d..3e1ff2c 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4033,6 +4033,10 @@ extern tree copy_node_stat (tree MEM_STAT_DECL);
 
 extern tree copy_list (tree);
 
+/* Make a CASE_LABEL_EXPR.  */
+
+extern tree build_case_label (tree, tree, tree);
+
 /* Make a BINFO.  */
 extern tree make_tree_binfo_stat (unsigned MEM_STAT_DECL);
 #define make_tree_binfo(t) make_tree_binfo_stat (t MEM_STAT_INFO)
-- 
1.7.0.4

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

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-11  4:30 ` [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses Nathan Froyd
@ 2011-03-11  8:12   ` Mike Stump
  2011-03-11 13:21   ` Richard Guenther
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 20+ messages in thread
From: Mike Stump @ 2011-03-11  8:12 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, Nathan Froyd, fortran, java-patches

The objective c bits are ok.

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

* Re: [4.7 PATCH 00/18] slim down a number of tree nodes
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (2 preceding siblings ...)
  2011-03-11  4:30 ` [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses Nathan Froyd
@ 2011-03-11  8:18 ` Mike Stump
  2011-03-11 16:00   ` Nathan Froyd
  2011-03-11  9:38 ` Andrew Haley
  2011-03-11 13:25 ` Richard Guenther
  5 siblings, 1 reply; 20+ messages in thread
From: Mike Stump @ 2011-03-11  8:18 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, Nathan Froyd, fortran, java-patches

On Mar 10, 2011, at 8:23 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> This patch series does something similar to what

I am curious what the speed differences are.

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

* Re: [4.7 PATCH 00/18] slim down a number of tree nodes
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (3 preceding siblings ...)
  2011-03-11  8:18 ` [4.7 PATCH 00/18] slim down a number of tree nodes Mike Stump
@ 2011-03-11  9:38 ` Andrew Haley
  2011-03-11 13:25 ` Richard Guenther
  5 siblings, 0 replies; 20+ messages in thread
From: Andrew Haley @ 2011-03-11  9:38 UTC (permalink / raw)
  To: java-patches

OK for Java.

Andrew.

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

* Re: [PATCH 07/18] generalize build_case_label to the rest of the compiler
  2011-03-11  4:30 ` [PATCH 07/18] generalize build_case_label to the rest of the compiler Nathan Froyd
@ 2011-03-11 13:01   ` Joseph S. Myers
  2011-03-11 13:10     ` Richard Guenther
  2011-03-11 14:56   ` Tom Tromey
  1 sibling, 1 reply; 20+ messages in thread
From: Joseph S. Myers @ 2011-03-11 13:01 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, fortran, java-patches

On Thu, 10 Mar 2011, Nathan Froyd wrote:

> This patch does lose location information on CASE_LABEL_EXPRs from the C
> family of front-ends; it did not seem worth it to have a number of
> places pass input_location when said information isn't even used.  I'm
> happy to add the location_t argument back to CASE_LABEL_EXPRs if people
> think that's worthwhile.

Since implicit use of input_location is deprecated and should be being 
phased out (making more locations explicit - including explicit 
input_location until the places using it have a better location 
available), I think you should keep the location argument.

The C front-end changes in this patch series (including c-family changes) 
are otherwise OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH 07/18] generalize build_case_label to the rest of the compiler
  2011-03-11 13:01   ` Joseph S. Myers
@ 2011-03-11 13:10     ` Richard Guenther
  0 siblings, 0 replies; 20+ messages in thread
From: Richard Guenther @ 2011-03-11 13:10 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Nathan Froyd, gcc-patches, fortran, java-patches

On Fri, Mar 11, 2011 at 2:01 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> On Thu, 10 Mar 2011, Nathan Froyd wrote:
>
>> This patch does lose location information on CASE_LABEL_EXPRs from the C
>> family of front-ends; it did not seem worth it to have a number of
>> places pass input_location when said information isn't even used.  I'm
>> happy to add the location_t argument back to CASE_LABEL_EXPRs if people
>> think that's worthwhile.
>
> Since implicit use of input_location is deprecated and should be being
> phased out (making more locations explicit - including explicit
> input_location until the places using it have a better location
> available), I think you should keep the location argument.
>
> The C front-end changes in this patch series (including c-family changes)
> are otherwise OK.

Yep, please pass UNKNOWN_LOCATION at callers that didn't set a
location (and add a location argument to build_case_label).

Thanks,
Richard.

> --
> Joseph S. Myers
> joseph@codesourcery.com
>

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

* Re: [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more
  2011-03-11  4:24 ` [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more Nathan Froyd
@ 2011-03-11 13:15   ` Richard Guenther
  2011-03-11 13:19     ` Nathan Froyd
  2011-03-11 15:14   ` Tom Tromey
  2011-03-12 12:23   ` Eric Botcazou
  2 siblings, 1 reply; 20+ messages in thread
From: Richard Guenther @ 2011-03-11 13:15 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, fortran, java-patches

On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> BLOCKs have a TREE_CHAIN and a TREE_TYPE; TREE_TYPE is useless for
> blocks, but we can't remove TREE_TYPE without also removing TREE_CHAIN.
> This patch lays the groundwork to do just that.  It changes places that
> use chainon on BLOCKs to use block_chainon, which works identically to
> chainon except it uses BLOCK_CHAIN.  And it fixes up a few places that
> used TREE_CHAIN when they meant BLOCK_CHAIN.

The middle-end parts are ok.  Any particular reason why you choose
function.[ch] for block_chainon and not tree.[ch]?

Thanks,
Richard.

> -Nathan
>
> gcc/ada/
>        * gcc-interface/utils.c (gnat_poplevel): Use block_chainon.
>
> gcc/
>        * function.h (block_chainon): Declare.
>        * function.c (block_chainon): Define.
>
> gcc/cp/
>        * decl.c (poplevel): Use block_chainon.
>
> gcc/fortran/
>        * f95-lang.c (poplevel): Use BLOCK_CHAIN and block_chainon.
>
> gcc/java/
>        * decl.c (poplevel): Use BLOCK_CHAIN and block_chainon.
>
> diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
> index eac87e0..dd06ca3 100644
> --- a/gcc/ada/gcc-interface/utils.c
> +++ b/gcc/ada/gcc-interface/utils.c
> @@ -395,8 +395,8 @@ gnat_poplevel (void)
>   else if (BLOCK_VARS (block) == NULL_TREE)
>     {
>       BLOCK_SUBBLOCKS (level->chain->block)
> -       = chainon (BLOCK_SUBBLOCKS (block),
> -                  BLOCK_SUBBLOCKS (level->chain->block));
> +       = block_chainon (BLOCK_SUBBLOCKS (block),
> +                        BLOCK_SUBBLOCKS (level->chain->block));
>       BLOCK_CHAIN (block) = free_block_chain;
>       free_block_chain = block;
>     }
> diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
> index a0ef39f..de96ac2 100644
> --- a/gcc/cp/decl.c
> +++ b/gcc/cp/decl.c
> @@ -794,7 +794,7 @@ poplevel (int keep, int reverse, int functionbody)
>     }
>   else if (block)
>     current_binding_level->blocks
> -      = chainon (current_binding_level->blocks, block);
> +      = block_chainon (current_binding_level->blocks, block);
>
>   /* If we did not make a block for the level just exited,
>      any blocks made for inner levels
> @@ -803,7 +803,7 @@ poplevel (int keep, int reverse, int functionbody)
>      of something else.  */
>   else if (subblocks)
>     current_binding_level->blocks
> -      = chainon (current_binding_level->blocks, subblocks);
> +      = block_chainon (current_binding_level->blocks, subblocks);
>
>   /* Each and every BLOCK node created here in `poplevel' is important
>      (e.g. for proper debugging information) so if we created one
> diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
> index 687f60b..aebe397 100644
> --- a/gcc/fortran/f95-lang.c
> +++ b/gcc/fortran/f95-lang.c
> @@ -444,7 +444,7 @@ poplevel (int keep, int reverse, int functionbody)
>
>   /* Record the BLOCK node just built as the subblock its enclosing scope.  */
>   for (subblock_node = subblock_chain; subblock_node;
> -       subblock_node = TREE_CHAIN (subblock_node))
> +       subblock_node = BLOCK_CHAIN (subblock_node))
>     BLOCK_SUPERCONTEXT (subblock_node) = block_node;
>
>   /* Clear out the meanings of the local variables of this level.  */
> @@ -475,7 +475,7 @@ poplevel (int keep, int reverse, int functionbody)
>   else if (block_node)
>     {
>       current_binding_level->blocks
> -       = chainon (current_binding_level->blocks, block_node);
> +       = block_chainon (current_binding_level->blocks, block_node);
>     }
>
>   /* If we did not make a block for the level just exited, any blocks made for
> @@ -484,7 +484,7 @@ poplevel (int keep, int reverse, int functionbody)
>      else.  */
>   else if (subblock_chain)
>     current_binding_level->blocks
> -      = chainon (current_binding_level->blocks, subblock_chain);
> +      = block_chainon (current_binding_level->blocks, subblock_chain);
>   if (block_node)
>     TREE_USED (block_node) = 1;
>
> diff --git a/gcc/function.c b/gcc/function.c
> index 3f721fb..094cf74 100644
> --- a/gcc/function.c
> +++ b/gcc/function.c
> @@ -4167,6 +4167,34 @@ blocks_nreverse (tree t)
>   return prev;
>  }
>
> +/* Concatenate two chains of blocks (chained through BLOCK_CHAIN)
> +   by modifying the last node in chain 1 to point to chain 2.  */
> +
> +tree
> +block_chainon (tree op1, tree op2)
> +{
> +  tree t1;
> +
> +  if (!op1)
> +    return op2;
> +  if (!op2)
> +    return op1;
> +
> +  for (t1 = op1; BLOCK_CHAIN (t1); t1 = BLOCK_CHAIN (t1))
> +    continue;
> +  BLOCK_CHAIN (t1) = op2;
> +
> +#ifdef ENABLE_TREE_CHECKING
> +  {
> +    tree t2;
> +    for (t2 = op2; t2; t2 = BLOCK_CHAIN (t2))
> +      gcc_assert (t2 != t1);
> +  }
> +#endif
> +
> +  return op1;
> +}
> +
>  /* Count the subblocks of the list starting with BLOCK.  If VECTOR is
>    non-NULL, list them all into VECTOR, in a depth-first preorder
>    traversal of the block tree.  Also clear TREE_ASM_WRITTEN in all
> diff --git a/gcc/function.h b/gcc/function.h
> index 6e7f539..73af294 100644
> --- a/gcc/function.h
> +++ b/gcc/function.h
> @@ -713,6 +713,7 @@ extern void number_blocks (tree);
>
>  extern void clear_block_marks (tree);
>  extern tree blocks_nreverse (tree);
> +extern tree block_chainon (tree, tree);
>
>  /* Return size needed for stack frame based on slots so far allocated.
>    This size counts from zero.  It is not rounded to STACK_BOUNDARY;
> diff --git a/gcc/java/decl.c b/gcc/java/decl.c
> index a17b826..6e94dff 100644
> --- a/gcc/java/decl.c
> +++ b/gcc/java/decl.c
> @@ -1481,7 +1481,7 @@ poplevel (int keep, int reverse, int functionbody)
>
>   /* In each subblock, record that this is its superior.  */
>
> -  for (link = subblocks; link; link = TREE_CHAIN (link))
> +  for (link = subblocks; link; link = BLOCK_CHAIN (link))
>     BLOCK_SUPERCONTEXT (link) = block;
>
>   /* Clear out the meanings of the local variables of this level.  */
> @@ -1545,7 +1545,7 @@ poplevel (int keep, int reverse, int functionbody)
>       if (block)
>        {
>          current_binding_level->blocks
> -           = chainon (current_binding_level->blocks, block);
> +           = block_chainon (current_binding_level->blocks, block);
>        }
>       /* If we did not make a block for the level just exited,
>         any blocks made for inner levels
> @@ -1554,7 +1554,7 @@ poplevel (int keep, int reverse, int functionbody)
>         of something else.  */
>       else if (subblocks)
>        current_binding_level->blocks
> -         = chainon (current_binding_level->blocks, subblocks);
> +         = block_chainon (current_binding_level->blocks, subblocks);
>
>       if (bind)
>        java_add_stmt (bind);
> --
> 1.7.0.4
>
>

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

* Re: [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more
  2011-03-11 13:15   ` Richard Guenther
@ 2011-03-11 13:19     ` Nathan Froyd
  0 siblings, 0 replies; 20+ messages in thread
From: Nathan Froyd @ 2011-03-11 13:19 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches, fortran, java-patches

On Fri, Mar 11, 2011 at 02:15:20PM +0100, Richard Guenther wrote:
> On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> > BLOCKs have a TREE_CHAIN and a TREE_TYPE; TREE_TYPE is useless for
> > blocks, but we can't remove TREE_TYPE without also removing TREE_CHAIN.
> > This patch lays the groundwork to do just that.  It changes places that
> > use chainon on BLOCKs to use block_chainon, which works identically to
> > chainon except it uses BLOCK_CHAIN.  And it fixes up a few places that
> > used TREE_CHAIN when they meant BLOCK_CHAIN.
> 
> The middle-end parts are ok.  Any particular reason why you choose
> function.[ch] for block_chainon and not tree.[ch]?

Because block_nreverse was already in function.[ch].  I'm not
particularly wedded to the location and can move it if you like (I did
spend some time looking through tree.[ch] before rgrep'ing and
remembering that block_nreverse was in a funny location...).

-Nathan

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

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-11  4:30 ` [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses Nathan Froyd
  2011-03-11  8:12   ` Mike Stump
@ 2011-03-11 13:21   ` Richard Guenther
  2011-03-11 15:24   ` Tom Tromey
  2011-03-12 12:13   ` Eric Botcazou
  3 siblings, 0 replies; 20+ messages in thread
From: Richard Guenther @ 2011-03-11 13:21 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, fortran, java-patches

On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> Now that we have a structure where not every node might include
> TREE_CHAIN or TREE_TYPE, we need to make sure that when we call said
> accessors that the argument is properly typed.  This requires a number
> of changes:
>
> - It's not enough for FEs to assume that FE-specific DECLs are the only
>  tree that needs to be marked specially; we need to mark things as
>  TS_TYPED or TS_COMMON.
>
> - To facilitate doing so, move the MARK_* macros for initializing
>  tree_contains_struct to tree.h so they are accessible to FEs.
>
> - Additionally, rearrange *_init_ts methods for the C-family languages
>  so that we can share code where code needs to be shared.
>
> - Finally, various places need to check for TS_COMMON structure before
>  blindly calling TREE_CHAIN.

The middle-end changes are ok for 4.7.

Thanks,
Richard.

> -Nathan
>
> gcc/ada/
>        * gcc-interface/ada-tree.h (union lang_tree_node): Check for
>        TS_COMMON before calling TREE_CHAIN.
>        * gcc-interface/misc.c (gnat_init_ts): New function.
>        (LANG_HOOKS_INIT_TS): Define.
>
> gcc/
>        * c-decl.c (union lang_tree_node): Check for TS_COMMON before
>        calling TREE_CHAIN.
>        * print-tree.c (print_node): Likewise.
>        * tree-inline.c (copy_tree_r): Likewise.
>        * c-lang.c (LANG_HOOKS_INIT_TS): Define.
>        * lto-streamer-in.c (lto_input_tree_pointers): Check for TS_TYPED
>        instead of TS_COMMON.
>        * lto-streamer-out.c (lto_output_tree_pointers): Likewise.
>        * tree.c (initialize_tree_contains_struct): Handle TS_TYPED.
>        (copy_node_stat): Zero TREE_CHAIN only if necessary.
>        (MARK_TS_BASE, MARK_TS_TYPED, MARK_TS_COMMON): Move these...
>        (MARK_TS_DECL_COMMON, MARK_TS_DECL_COMMON, MARK_TS_DECL_WRTL):
>        ...and these...
>        (MARK_TS_DECL_WITH_VIS, MARK_TS_DECL_NON_COMMON): ...and these...
>        * tree.h: ...here.
>        (TREE_CHAIN): Check for a TS_COMMON structure.
>        (TREE_TYPE): Check for a TS_TYPED structure.
>
> gcc/c-family/
>        * c-common.h (c_common_init_ts): Declare.
>        * c-common.c (c_common_init_ts): Define.
>
> gcc/cp/
>        * cp-lang.c (cp_init_ts): Call cp_common_init_ts.  Move
>        tree_contains_struct initialization to...
>        * cp-objcp-common.c (cp_common_init_ts): ...here.  Use MARK_*
>        macros.
>        * cp-objcp-common.h (cp_common_init_ts): Declare.
>        * cp-tree.h (union lang_tree_node): Check for TS_COMMON before
>        calling TREE_CHAIN.
>
> gcc/fortran/
>        * f95-lang.c (union lang_tree_node): Check for TS_COMMON before
>        calling TREE_CHAIN.
>
> gcc/go/
>        * go-lang.c (union lang_tree_node): Check for TS_COMMON before
>        calling TREE_CHAIN.
>
> gcc/java/
>        * java-tree.h (union lang_tree_node): Check for TS_COMMON before
>        calling TREE_CHAIN.
>
> gcc/lto/
>        * lto-tree.h (union lang_tree_node): Check for TS_COMMON before
>        calling TREE_CHAIN.
>        * lto.c (lto_fixup_common): Likewise.
>
> gcc/objc/
>        * objc-lang.c (objc_init_ts): Move code for this function...
>        * objc-act.c (objc_common_init_ts): ...here. Define.
>        * objc-act.h (objc_common_init_ts): Declare.
>
> gcc/objcp/
>        * objcp-lang.c (objcxx_init_ts): Call objc_common_init_ts and
>        cp_common_init_ts.
>
> diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h
> index 9002fa1..3542349 100644
> --- a/gcc/ada/gcc-interface/ada-tree.h
> +++ b/gcc/ada/gcc-interface/ada-tree.h
> @@ -25,7 +25,7 @@
>
>  /* The resulting tree type.  */
>  union GTY((desc ("0"),
> -          chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
> +          chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
>   lang_tree_node
>  {
>   union tree_node GTY((tag ("0"),
> diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
> index 4f7a5e1..89823ca 100644
> --- a/gcc/ada/gcc-interface/misc.c
> +++ b/gcc/ada/gcc-interface/misc.c
> @@ -696,6 +696,20 @@ gnat_eh_personality (void)
>   return gnat_eh_personality_decl;
>  }
>
> +/* Initialize language-specific bits of tree_contains_struct.  */
> +
> +static void
> +gnat_init_ts (void)
> +{
> +  MARK_TS_COMMON (UNCONSTRAINED_ARRAY_TYPE);
> +
> +  MARK_TS_TYPED (UNCONSTRAINED_ARRAY_REF);
> +  MARK_TS_TYPED (LOOP_STMT);
> +  MARK_TS_TYPED (STMT_STMT);
> +  MARK_TS_TYPED (EXIT_STMT);
> +  MARK_TS_TYPED (NULL_EXPR);
> +}
> +
>  /* Definitions for our language-specific hooks.  */
>
>  #undef  LANG_HOOKS_NAME
> @@ -754,6 +768,8 @@ gnat_eh_personality (void)
>  #define LANG_HOOKS_EH_PERSONALITY      gnat_eh_personality
>  #undef  LANG_HOOKS_DEEP_UNSHARING
>  #define LANG_HOOKS_DEEP_UNSHARING      true
> +#undef  LANG_HOOKS_INIT_TS
> +#define LANG_HOOKS_INIT_TS             gnat_init_ts
>
>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
>
> diff --git a/gcc/c-decl.c b/gcc/c-decl.c
> index b438b06..14aef5f 100644
> --- a/gcc/c-decl.c
> +++ b/gcc/c-decl.c
> @@ -242,7 +242,7 @@ extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
>  /* The resulting tree type.  */
>
>  union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
> -       chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) TREE_CHAIN (&%h.generic))")))  lang_tree_node
> +       chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))  lang_tree_node
>  {
>   union tree_node GTY ((tag ("0"),
>                        desc ("tree_node_structure (&%h)")))
> diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
> index d696b5f..7207335 100644
> --- a/gcc/c-family/c-common.c
> +++ b/gcc/c-family/c-common.c
> @@ -9692,4 +9692,13 @@ keyword_is_decl_specifier (enum rid keyword)
>     }
>  }
>
> +/* Initialize language-specific-bits of tree_contains_struct.  */
> +
> +void
> +c_common_init_ts (void)
> +{
> +  MARK_TS_TYPED (C_MAYBE_CONST_EXPR);
> +  MARK_TS_TYPED (EXCESS_PRECISION_EXPR);
> +}
> +
>  #include "gt-c-family-c-common.h"
> diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
> index 406def9..7e4f0a1 100644
> --- a/gcc/c-family/c-common.h
> +++ b/gcc/c-family/c-common.h
> @@ -707,6 +707,7 @@ extern tree c_common_fixed_point_type_for_size (unsigned int, unsigned int,
>  extern tree c_common_unsigned_type (tree);
>  extern tree c_common_signed_type (tree);
>  extern tree c_common_signed_or_unsigned_type (int, tree);
> +extern void c_common_init_ts (void);
>  extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int);
>  extern bool decl_with_nonnull_addr_p (const_tree);
>  extern tree c_fully_fold (tree, bool, bool *);
> diff --git a/gcc/c-lang.c b/gcc/c-lang.c
> index 0ca2e7c..ae1b081 100644
> --- a/gcc/c-lang.c
> +++ b/gcc/c-lang.c
> @@ -43,6 +43,8 @@ enum c_language_kind c_language = clk_c;
>  #define LANG_HOOKS_NAME "GNU C"
>  #undef LANG_HOOKS_INIT
>  #define LANG_HOOKS_INIT c_objc_common_init
> +#undef LANG_HOOKS_INIT_TS
> +#define LANG_HOOKS_INIT_TS c_common_init_ts
>
>  /* Each front end provides its own lang hook initializer.  */
>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
> diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
> index e5c1c09..6506930 100644
> --- a/gcc/cp/cp-lang.c
> +++ b/gcc/cp/cp-lang.c
> @@ -100,32 +100,12 @@ objcp_tsubst_copy_and_build (tree t ATTRIBUTE_UNUSED,
>   return NULL_TREE;
>  }
>
> -
>  static void
>  cp_init_ts (void)
>  {
> -  tree_contains_struct[NAMESPACE_DECL][TS_DECL_NON_COMMON] = 1;
> -  tree_contains_struct[USING_DECL][TS_DECL_NON_COMMON] = 1;
> -  tree_contains_struct[TEMPLATE_DECL][TS_DECL_NON_COMMON] = 1;
> -
> -  tree_contains_struct[NAMESPACE_DECL][TS_DECL_WITH_VIS] = 1;
> -  tree_contains_struct[USING_DECL][TS_DECL_WITH_VIS] = 1;
> -  tree_contains_struct[TEMPLATE_DECL][TS_DECL_WITH_VIS] = 1;
> -
> -  tree_contains_struct[NAMESPACE_DECL][TS_DECL_WRTL] = 1;
> -  tree_contains_struct[USING_DECL][TS_DECL_WRTL] = 1;
> -  tree_contains_struct[TEMPLATE_DECL][TS_DECL_WRTL] = 1;
> -
> -  tree_contains_struct[NAMESPACE_DECL][TS_DECL_COMMON] = 1;
> -  tree_contains_struct[USING_DECL][TS_DECL_COMMON] = 1;
> -  tree_contains_struct[TEMPLATE_DECL][TS_DECL_COMMON] = 1;
> -
> -  tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1;
> -  tree_contains_struct[USING_DECL][TS_DECL_MINIMAL] = 1;
> -  tree_contains_struct[TEMPLATE_DECL][TS_DECL_MINIMAL] = 1;
> +  cp_common_init_ts ();
>
>   init_shadowed_var_for_decl ();
> -
>  }
>
>  static const char *
> diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
> index f045d29..66d2d27 100644
> --- a/gcc/cp/cp-objcp-common.c
> +++ b/gcc/cp/cp-objcp-common.c
> @@ -222,5 +222,78 @@ init_shadowed_var_for_decl (void)
>                                           tree_decl_map_eq, 0);
>  }
>
> +void
> +cp_common_init_ts (void)
> +{
> +  MARK_TS_DECL_NON_COMMON (NAMESPACE_DECL);
> +  MARK_TS_DECL_NON_COMMON (USING_DECL);
> +  MARK_TS_DECL_NON_COMMON (TEMPLATE_DECL);
> +
> +  MARK_TS_COMMON (TEMPLATE_TEMPLATE_PARM);
> +  MARK_TS_COMMON (TEMPLATE_TYPE_PARM);
> +  MARK_TS_COMMON (TEMPLATE_PARM_INDEX);
> +  MARK_TS_COMMON (OVERLOAD);
> +  MARK_TS_COMMON (TEMPLATE_INFO);
> +  MARK_TS_COMMON (FOR_STMT);
> +  MARK_TS_COMMON (TYPENAME_TYPE);
> +  MARK_TS_COMMON (TYPEOF_TYPE);
> +  MARK_TS_COMMON (IF_STMT);
> +  MARK_TS_COMMON (BASELINK);
> +  MARK_TS_COMMON (SWITCH_STMT);
> +  MARK_TS_COMMON (TYPE_PACK_EXPANSION);
> +  MARK_TS_COMMON (EXPR_PACK_EXPANSION);
> +  MARK_TS_COMMON (DECLTYPE_TYPE);
> +  MARK_TS_COMMON (BOUND_TEMPLATE_TEMPLATE_PARM);
> +  MARK_TS_COMMON (UNBOUND_CLASS_TEMPLATE);
> +  MARK_TS_COMMON (RANGE_FOR_STMT);
> +
> +  MARK_TS_TYPED (AGGR_INIT_EXPR);
> +  MARK_TS_TYPED (EXPR_STMT);
> +  MARK_TS_TYPED (EH_SPEC_BLOCK);
> +  MARK_TS_TYPED (CLEANUP_STMT);
> +  MARK_TS_TYPED (SCOPE_REF);
> +  MARK_TS_TYPED (CAST_EXPR);
> +  MARK_TS_TYPED (NON_DEPENDENT_EXPR);
> +  MARK_TS_TYPED (MODOP_EXPR);
> +  MARK_TS_TYPED (TRY_BLOCK);
> +  MARK_TS_TYPED (THROW_EXPR);
> +  MARK_TS_TYPED (HANDLER);
> +  MARK_TS_TYPED (REINTERPRET_CAST_EXPR);
> +  MARK_TS_TYPED (CONST_CAST_EXPR);
> +  MARK_TS_TYPED (STATIC_CAST_EXPR);
> +  MARK_TS_TYPED (DYNAMIC_CAST_EXPR);
> +  MARK_TS_TYPED (TEMPLATE_ID_EXPR);
> +  MARK_TS_TYPED (ARROW_EXPR);
> +  MARK_TS_TYPED (SIZEOF_EXPR);
> +  MARK_TS_TYPED (ALIGNOF_EXPR);
> +  MARK_TS_TYPED (AT_ENCODE_EXPR);
> +  MARK_TS_TYPED (UNARY_PLUS_EXPR);
> +  MARK_TS_TYPED (TRAIT_EXPR);
> +  MARK_TS_TYPED (TYPE_ARGUMENT_PACK);
> +  MARK_TS_TYPED (NOEXCEPT_EXPR);
> +  MARK_TS_TYPED (NONTYPE_ARGUMENT_PACK);
> +  MARK_TS_TYPED (WHILE_STMT);
> +  MARK_TS_TYPED (NEW_EXPR);
> +  MARK_TS_TYPED (VEC_NEW_EXPR);
> +  MARK_TS_TYPED (BREAK_STMT);
> +  MARK_TS_TYPED (MEMBER_REF);
> +  MARK_TS_TYPED (DOTSTAR_EXPR);
> +  MARK_TS_TYPED (DO_STMT);
> +  MARK_TS_TYPED (DELETE_EXPR);
> +  MARK_TS_TYPED (VEC_DELETE_EXPR);
> +  MARK_TS_TYPED (CONTINUE_STMT);
> +  MARK_TS_TYPED (TAG_DEFN);
> +  MARK_TS_TYPED (PSEUDO_DTOR_EXPR);
> +  MARK_TS_TYPED (TYPEID_EXPR);
> +  MARK_TS_TYPED (MUST_NOT_THROW_EXPR);
> +  MARK_TS_TYPED (STMT_EXPR);
> +  MARK_TS_TYPED (OFFSET_REF);
> +  MARK_TS_TYPED (OFFSETOF_EXPR);
> +  MARK_TS_TYPED (PTRMEM_CST);
> +  MARK_TS_TYPED (EMPTY_CLASS_EXPR);
> +  MARK_TS_TYPED (VEC_INIT_EXPR);
> +  MARK_TS_TYPED (USING_STMT);
> +  MARK_TS_TYPED (LAMBDA_EXPR);
> +}
>
>  #include "gt-cp-cp-objcp-common.h"
> diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
> index 38da59e..c668ad8 100644
> --- a/gcc/cp/cp-objcp-common.h
> +++ b/gcc/cp/cp-objcp-common.h
> @@ -28,6 +28,7 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
>                                         tree, bool);
>
>  extern bool cp_function_decl_explicit_p (tree decl);
> +extern void cp_common_init_ts (void);
>
>  /* Lang hooks that are shared between C++ and ObjC++ are defined here.  Hooks
>    specific to C++ or ObjC++ go in cp/cp-lang.c and objcp/objcp-lang.c,
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index 238d0cf..1783915 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -702,7 +702,7 @@ enum cp_tree_node_structure_enum {
>
>  /* The resulting tree type.  */
>  union GTY((desc ("cp_tree_node_structure (&%h)"),
> -       chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)"))) lang_tree_node {
> +       chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL"))) lang_tree_node {
>   union tree_node GTY ((tag ("TS_CP_GENERIC"),
>                        desc ("tree_node_structure (&%h)"))) generic;
>   struct template_parm_index_s GTY ((tag ("TS_CP_TPI"))) tpi;
> diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
> index a3ac860..687f60b 100644
> --- a/gcc/fortran/f95-lang.c
> +++ b/gcc/fortran/f95-lang.c
> @@ -59,7 +59,7 @@ lang_identifier {
>  /* The resulting tree type.  */
>
>  union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
> -     chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
> +     chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
>
>  lang_tree_node {
>   union tree_node GTY((tag ("0"),
> diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c
> index b59e72d..5132e97 100644
> --- a/gcc/go/go-lang.c
> +++ b/gcc/go/go-lang.c
> @@ -65,7 +65,7 @@ struct GTY(()) lang_identifier
>  /* The resulting tree type.  */
>
>  union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
> -          chain_next ("(union lang_tree_node *) TREE_CHAIN (&%h.generic)")))
> +          chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
>  lang_tree_node
>  {
>   union tree_node GTY((tag ("0"),
> diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
> index 3addcca..e422b4a 100644
> --- a/gcc/java/java-tree.h
> +++ b/gcc/java/java-tree.h
> @@ -587,7 +587,7 @@ struct GTY(()) lang_identifier {
>
>  /* The resulting tree type.  */
>  union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
> -       chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
> +       chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
>
>   lang_tree_node {
>   union tree_node GTY ((tag ("0"),
> diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
> index 7409c1a..45809b8 100644
> --- a/gcc/lto-streamer-in.c
> +++ b/gcc/lto-streamer-in.c
> @@ -2326,7 +2326,7 @@ lto_input_tree_pointers (struct lto_input_block *ib, struct data_in *data_in,
>
>   code = TREE_CODE (expr);
>
> -  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
> +  if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
>     lto_input_ts_common_tree_pointers (ib, data_in, expr);
>
>   if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
> diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
> index 29d171b..a4e8b70 100644
> --- a/gcc/lto-streamer-out.c
> +++ b/gcc/lto-streamer-out.c
> @@ -1169,7 +1169,7 @@ lto_output_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
>
>   code = TREE_CODE (expr);
>
> -  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
> +  if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
>     lto_output_ts_common_tree_pointers (ob, expr, ref_p);
>
>   if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
> diff --git a/gcc/lto/lto-tree.h b/gcc/lto/lto-tree.h
> index d187fe2..847348c 100644
> --- a/gcc/lto/lto-tree.h
> +++ b/gcc/lto/lto-tree.h
> @@ -48,7 +48,7 @@ enum lto_tree_node_structure_enum {
>  };
>
>  union GTY((desc ("lto_tree_node_structure (&%h)"),
> -         chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
> +         chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
>     lang_tree_node
>  {
>   union tree_node GTY ((tag ("TS_LTO_GENERIC"),
> diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
> index 71c8cdb..78a7977 100644
> --- a/gcc/lto/lto.c
> +++ b/gcc/lto/lto.c
> @@ -1618,7 +1618,8 @@ lto_fixup_common (tree t, void *data)
>
>   /* This is not very efficient because we cannot do tail-recursion with
>      a long chain of trees. */
> -  LTO_FIXUP_SUBTREE (TREE_CHAIN (t));
> +  if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_COMMON))
> +    LTO_FIXUP_SUBTREE (TREE_CHAIN (t));
>  }
>
>  /* Fix up fields of a decl_minimal T.  DATA points to fix-up states.  */
> diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
> index 049dc00..e5bd52a 100644
> --- a/gcc/objc/objc-act.c
> +++ b/gcc/objc/objc-act.c
> @@ -10541,4 +10541,22 @@ objc_v2_encode_prop_attr (tree property)
>   return get_identifier (string);
>  }
>
> +void
> +objc_common_init_ts (void)
> +{
> +  c_common_init_ts ();
> +
> +  MARK_TS_DECL_NON_COMMON (CLASS_METHOD_DECL);
> +  MARK_TS_DECL_NON_COMMON (INSTANCE_METHOD_DECL);
> +  MARK_TS_DECL_NON_COMMON (KEYWORD_DECL);
> +  MARK_TS_DECL_NON_COMMON (PROPERTY_DECL);
> +
> +  MARK_TS_COMMON (CLASS_INTERFACE_TYPE);
> +  MARK_TS_COMMON (PROTOCOL_INTERFACE_TYPE);
> +  MARK_TS_COMMON (CLASS_IMPLEMENTATION_TYPE);
> +
> +  MARK_TS_TYPED (MESSAGE_SEND_EXPR);
> +  MARK_TS_TYPED (PROPERTY_REF);
> +}
> +
>  #include "gt-objc-objc-act.h"
> diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h
> index 3983d4b..909181a 100644
> --- a/gcc/objc/objc-act.h
> +++ b/gcc/objc/objc-act.h
> @@ -28,6 +28,7 @@ bool objc_init (void);
>  const char *objc_printable_name (tree, int);
>  tree objc_fold_obj_type_ref (tree, tree);
>  int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
> +void objc_common_init_ts (void);
>
>  /* NB: The remaining public functions are prototyped in c-common.h, for the
>    benefit of stub-objc.c and objc-act.c.  */
> diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c
> index fd65776..169b894 100644
> --- a/gcc/objc/objc-lang.c
> +++ b/gcc/objc/objc-lang.c
> @@ -36,7 +36,6 @@ along with GCC; see the file COPYING3.  If not see
>  #include "c-lang.h"
>
>  enum c_language_kind c_language = clk_objc;
> -static void objc_init_ts (void);
>
>  /* Lang hooks common to C and ObjC are declared in c-objc-common.h;
>    consequently, there should be very few hooks below.  */
> @@ -50,7 +49,7 @@ static void objc_init_ts (void);
>  #undef LANG_HOOKS_GIMPLIFY_EXPR
>  #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
>  #undef LANG_HOOKS_INIT_TS
> -#define LANG_HOOKS_INIT_TS objc_init_ts
> +#define LANG_HOOKS_INIT_TS objc_common_init_ts
>
>  /* Each front end provides its own lang hook initializer.  */
>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
> @@ -58,33 +57,4 @@ struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
>  /* Lang hook routines common to C and ObjC appear in c-objc-common.c;
>    there should be very few (if any) routines below.  */
>
> -static void
> -objc_init_ts (void)
> -{
> -  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_NON_COMMON] = 1;
> -  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_NON_COMMON] = 1;
> -  tree_contains_struct[KEYWORD_DECL][TS_DECL_NON_COMMON] = 1;
> -  tree_contains_struct[PROPERTY_DECL][TS_DECL_NON_COMMON] = 1;
> -
> -  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_WITH_VIS] = 1;
> -  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_WITH_VIS] = 1;
> -  tree_contains_struct[KEYWORD_DECL][TS_DECL_WITH_VIS] = 1;
> -  tree_contains_struct[PROPERTY_DECL][TS_DECL_WITH_VIS] = 1;
> -
> -  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_WRTL] = 1;
> -  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_WRTL] = 1;
> -  tree_contains_struct[KEYWORD_DECL][TS_DECL_WRTL] = 1;
> -  tree_contains_struct[PROPERTY_DECL][TS_DECL_WRTL] = 1;
> -
> -  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_MINIMAL] = 1;
> -  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_MINIMAL] = 1;
> -  tree_contains_struct[KEYWORD_DECL][TS_DECL_MINIMAL] = 1;
> -  tree_contains_struct[PROPERTY_DECL][TS_DECL_MINIMAL] = 1;
> -
> -  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_COMMON] = 1;
> -  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_COMMON] = 1;
> -  tree_contains_struct[KEYWORD_DECL][TS_DECL_COMMON] = 1;
> -  tree_contains_struct[PROPERTY_DECL][TS_DECL_COMMON] = 1;
> -}
> -
>  #include "gtype-objc.h"
> diff --git a/gcc/objcp/objcp-lang.c b/gcc/objcp/objcp-lang.c
> index fe2be66..0019022 100644
> --- a/gcc/objcp/objcp-lang.c
> +++ b/gcc/objcp/objcp-lang.c
> @@ -89,52 +89,8 @@ objcp_tsubst_copy_and_build (tree t, tree args, tsubst_flags_t complain,
>  static void
>  objcxx_init_ts (void)
>  {
> -  /* objc decls */
> -  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_NON_COMMON] = 1;
> -  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_NON_COMMON] = 1;
> -  tree_contains_struct[KEYWORD_DECL][TS_DECL_NON_COMMON] = 1;
> -  tree_contains_struct[PROPERTY_DECL][TS_DECL_NON_COMMON] = 1;
> -
> -  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_WITH_VIS] = 1;
> -  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_WITH_VIS] = 1;
> -  tree_contains_struct[KEYWORD_DECL][TS_DECL_WITH_VIS] = 1;
> -  tree_contains_struct[PROPERTY_DECL][TS_DECL_WITH_VIS] = 1;
> -
> -  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_WRTL] = 1;
> -  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_WRTL] = 1;
> -  tree_contains_struct[KEYWORD_DECL][TS_DECL_WRTL] = 1;
> -  tree_contains_struct[PROPERTY_DECL][TS_DECL_WRTL] = 1;
> -
> -  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_MINIMAL] = 1;
> -  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_MINIMAL] = 1;
> -  tree_contains_struct[KEYWORD_DECL][TS_DECL_MINIMAL] = 1;
> -  tree_contains_struct[PROPERTY_DECL][TS_DECL_MINIMAL] = 1;
> -
> -  tree_contains_struct[CLASS_METHOD_DECL][TS_DECL_COMMON] = 1;
> -  tree_contains_struct[INSTANCE_METHOD_DECL][TS_DECL_COMMON] = 1;
> -  tree_contains_struct[KEYWORD_DECL][TS_DECL_COMMON] = 1;
> -  tree_contains_struct[PROPERTY_DECL][TS_DECL_COMMON] = 1;
> -
> -  /* C++ decls */
> -  tree_contains_struct[NAMESPACE_DECL][TS_DECL_NON_COMMON] = 1;
> -  tree_contains_struct[USING_DECL][TS_DECL_NON_COMMON] = 1;
> -  tree_contains_struct[TEMPLATE_DECL][TS_DECL_NON_COMMON] = 1;
> -
> -  tree_contains_struct[NAMESPACE_DECL][TS_DECL_WITH_VIS] = 1;
> -  tree_contains_struct[USING_DECL][TS_DECL_WITH_VIS] = 1;
> -  tree_contains_struct[TEMPLATE_DECL][TS_DECL_WITH_VIS] = 1;
> -
> -  tree_contains_struct[NAMESPACE_DECL][TS_DECL_WRTL] = 1;
> -  tree_contains_struct[USING_DECL][TS_DECL_WRTL] = 1;
> -  tree_contains_struct[TEMPLATE_DECL][TS_DECL_WRTL] = 1;
> -
> -  tree_contains_struct[NAMESPACE_DECL][TS_DECL_COMMON] = 1;
> -  tree_contains_struct[USING_DECL][TS_DECL_COMMON] = 1;
> -  tree_contains_struct[TEMPLATE_DECL][TS_DECL_COMMON] = 1;
> -
> -  tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1;
> -  tree_contains_struct[USING_DECL][TS_DECL_MINIMAL] = 1;
> -  tree_contains_struct[TEMPLATE_DECL][TS_DECL_MINIMAL] = 1;
> +  objc_common_init_ts ();
> +  cp_common_init_ts ();
>
>   init_shadowed_var_for_decl ();
>  }
> diff --git a/gcc/print-tree.c b/gcc/print-tree.c
> index dfd3589..b0c6899 100644
> --- a/gcc/print-tree.c
> +++ b/gcc/print-tree.c
> @@ -756,7 +756,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
>              print_node (file, temp, TREE_OPERAND (node, i), indent + 4);
>            }
>        }
> -      print_node (file, "chain", TREE_CHAIN (node), indent + 4);
> +      if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
> +       print_node (file, "chain", TREE_CHAIN (node), indent + 4);
>       break;
>
>     case tcc_constant:
> diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
> index de30cfd..45c7e88 100644
> --- a/gcc/tree-inline.c
> +++ b/gcc/tree-inline.c
> @@ -4295,7 +4295,8 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
>         here.  */
>       tree chain = NULL_TREE, new_tree;
>
> -      chain = TREE_CHAIN (*tp);
> +      if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
> +       chain = TREE_CHAIN (*tp);
>
>       /* Copy the node.  */
>       new_tree = copy_node (*tp);
> diff --git a/gcc/tree.c b/gcc/tree.c
> index 798bc08..68f40c9 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -351,53 +351,6 @@ initialize_tree_contains_struct (void)
>  {
>   unsigned i;
>
> -#define MARK_TS_BASE(C)                                        \
> -  do {                                                 \
> -    tree_contains_struct[C][TS_BASE] = 1;              \
> -  } while (0)
> -
> -#define MARK_TS_TYPED(C)                               \
> -  do {                                                 \
> -    MARK_TS_BASE (C);                                  \
> -    tree_contains_struct[C][TS_TYPED] = 1;             \
> -  } while (0)
> -
> -#define MARK_TS_COMMON(C)                              \
> -  do {                                                 \
> -    MARK_TS_TYPED (C);                                 \
> -    tree_contains_struct[C][TS_COMMON] = 1;            \
> -  } while (0)
> -
> -#define MARK_TS_DECL_MINIMAL(C)                                \
> -  do {                                                 \
> -    MARK_TS_COMMON (C);                                        \
> -    tree_contains_struct[C][TS_DECL_MINIMAL] = 1;      \
> -  } while (0)
> -
> -#define MARK_TS_DECL_COMMON(C)                         \
> -  do {                                                 \
> -    MARK_TS_DECL_MINIMAL (C);                          \
> -    tree_contains_struct[C][TS_DECL_COMMON] = 1;       \
> -  } while (0)
> -
> -#define MARK_TS_DECL_WRTL(C)                           \
> -  do {                                                 \
> -    MARK_TS_DECL_COMMON (C);                           \
> -    tree_contains_struct[C][TS_DECL_WRTL] = 1;         \
> -  } while (0)
> -
> -#define MARK_TS_DECL_WITH_VIS(C)                       \
> -  do {                                                 \
> -    MARK_TS_DECL_WRTL (C);                             \
> -    tree_contains_struct[C][TS_DECL_WITH_VIS] = 1;     \
> -  } while (0)
> -
> -#define MARK_TS_DECL_NON_COMMON(C)                     \
> -  do {                                                 \
> -    MARK_TS_DECL_WITH_VIS (C);                         \
> -    tree_contains_struct[C][TS_DECL_NON_COMMON] = 1;   \
> -  } while (0)
> -
>   for (i = ERROR_MARK; i < LAST_AND_UNUSED_TREE_CODE; i++)
>     {
>       enum tree_code code;
> @@ -412,10 +365,14 @@ initialize_tree_contains_struct (void)
>       /* Mark all the structures that TS is derived from.  */
>       switch (ts_code)
>        {
> -       case TS_COMMON:
> +       case TS_TYPED:
>          MARK_TS_BASE (code);
>          break;
>
> +       case TS_COMMON:
> +         MARK_TS_TYPED (code);
> +         break;
> +
>        case TS_INT_CST:
>        case TS_REAL_CST:
>        case TS_FIXED_CST:
> @@ -521,14 +478,6 @@ initialize_tree_contains_struct (void)
>   gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL]);
>   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL]);
>   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON]);
> -
> -#undef MARK_TS_BASE
> -#undef MARK_TS_COMMON
> -#undef MARK_TS_DECL_MINIMAL
> -#undef MARK_TS_DECL_COMMON
> -#undef MARK_TS_DECL_WRTL
> -#undef MARK_TS_DECL_WITH_VIS
> -#undef MARK_TS_DECL_NON_COMMON
>  }
>
>
> @@ -944,7 +893,7 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
>  }
>
>  /* Return a new node with the same contents as NODE except that its
> -   TREE_CHAIN is zero and it has a fresh uid.  */
> +   TREE_CHAIN, if it has one, is zero and it has a fresh uid.  */
>
>  tree
>  copy_node_stat (tree node MEM_STAT_DECL)
> @@ -959,7 +908,8 @@ copy_node_stat (tree node MEM_STAT_DECL)
>   t = ggc_alloc_zone_tree_node_stat (&tree_zone, length PASS_MEM_STAT);
>   memcpy (t, node, length);
>
> -  TREE_CHAIN (t) = 0;
> +  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
> +    TREE_CHAIN (t) = 0;
>   TREE_ASM_WRITTEN (t) = 0;
>   TREE_VISITED (t) = 0;
>   if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 2f772e1..4ad2d3e 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -50,6 +50,54 @@ MAX_TREE_CODES
>  extern unsigned char tree_contains_struct[MAX_TREE_CODES][64];
>  #define CODE_CONTAINS_STRUCT(CODE, STRUCT) (tree_contains_struct[(CODE)][(STRUCT)])
>
> +/* Macros for initializing `tree_contains_struct'.  */
> +#define MARK_TS_BASE(C)                                        \
> +  do {                                                 \
> +    tree_contains_struct[C][TS_BASE] = 1;              \
> +  } while (0)
> +
> +#define MARK_TS_TYPED(C)                               \
> +  do {                                                 \
> +    MARK_TS_BASE (C);                                  \
> +    tree_contains_struct[C][TS_TYPED] = 1;             \
> +  } while (0)
> +
> +#define MARK_TS_COMMON(C)                              \
> +  do {                                                 \
> +    MARK_TS_TYPED (C);                                 \
> +    tree_contains_struct[C][TS_COMMON] = 1;            \
> +  } while (0)
> +
> +#define MARK_TS_DECL_MINIMAL(C)                                \
> +  do {                                                 \
> +    MARK_TS_COMMON (C);                                        \
> +    tree_contains_struct[C][TS_DECL_MINIMAL] = 1;      \
> +  } while (0)
> +
> +#define MARK_TS_DECL_COMMON(C)                         \
> +  do {                                                 \
> +    MARK_TS_DECL_MINIMAL (C);                          \
> +    tree_contains_struct[C][TS_DECL_COMMON] = 1;       \
> +  } while (0)
> +
> +#define MARK_TS_DECL_WRTL(C)                           \
> +  do {                                                 \
> +    MARK_TS_DECL_COMMON (C);                           \
> +    tree_contains_struct[C][TS_DECL_WRTL] = 1;         \
> +  } while (0)
> +
> +#define MARK_TS_DECL_WITH_VIS(C)                       \
> +  do {                                                 \
> +    MARK_TS_DECL_WRTL (C);                             \
> +    tree_contains_struct[C][TS_DECL_WITH_VIS] = 1;     \
> +  } while (0)
> +
> +#define MARK_TS_DECL_NON_COMMON(C)                     \
> +  do {                                                 \
> +    MARK_TS_DECL_WITH_VIS (C);                         \
> +    tree_contains_struct[C][TS_DECL_NON_COMMON] = 1;   \
> +  } while (0)
> +
>  /* Number of language-independent tree codes.  */
>  #define NUM_TREE_CODES ((int) LAST_AND_UNUSED_TREE_CODE)
>
> @@ -864,7 +912,7 @@ enum tree_node_structure_enum {
>    are chained together.  */
>
>  #define TREE_CHAIN(NODE) __extension__ \
> -(*({__typeof (NODE) const __t = (NODE);                                \
> +(*({__typeof (NODE) const __t = CONTAINS_STRUCT_CHECK (NODE, TS_COMMON);\
>     &__t->common.chain; }))
>
>  /* In all nodes that are expressions, this is the data type of the expression.
> @@ -872,7 +920,7 @@ enum tree_node_structure_enum {
>    In ARRAY_TYPE nodes, this is the type of the elements.
>    In VECTOR_TYPE nodes, this is the type of the elements.  */
>  #define TREE_TYPE(NODE) __extension__ \
> -(*({__typeof (NODE) const __t = (NODE);                                        \
> +(*({__typeof (NODE) const __t = CONTAINS_STRUCT_CHECK (NODE, TS_TYPED); \
>     &__t->typed.type; }))
>
>  extern void tree_contains_struct_check_failed (const_tree,
> --
> 1.7.0.4
>
>

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

* Re: [4.7 PATCH 00/18] slim down a number of tree nodes
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (4 preceding siblings ...)
  2011-03-11  9:38 ` Andrew Haley
@ 2011-03-11 13:25 ` Richard Guenther
  2011-03-11 13:42   ` Nathan Froyd
  5 siblings, 1 reply; 20+ messages in thread
From: Richard Guenther @ 2011-03-11 13:25 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, fortran, java-patches

On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> This patch series does something similar to what:
>
> http://gcc.gnu.org/ml/gcc-patches/2010-11/msg02491.html
>
> did, only it does it in a cleaner way and it addresses the problem more
> generally.  It introduces a separate substructure (base class) for tree
> nodes that include TREE_TYPE so that a tree node can use TREE_TYPE
> without having to deal with TREE_CHAIN.  It then goes about making
> changes where necessary to both use this new substructure and eliminate
> unnecessary TREE_CHAIN usage.
>
> Eliminating the block field from tree_exp would be another nice-to-have
> for 4.7, but that's not on my radar of things to address at the moment.
> (Matz, you want to do that? :)  Eliminating TREE_TYPE from tree_exp as
> suggested on the wiki would be another interesting project, but not one
> I plan on tackling.

I think removing TREE_TYPE from tree_exp isn't worth it, we do not have
many expression trees left with tuples.  Unifying BLOCK with locations
would indeed be nice (but again we don't have many exp trees left).

> The patch series touches every front-end in various places.  I have CC'd
> the appropriate mailing lists with this introductory email, but I will
> only CC those mailing lists on followup patches that touch the
> appropriate FE.
>
> I have not rigorously measured memory savings with this patch.  Based on
> a (very small) sample, this patch saves ~5% of tree memory according to
> dump_tree_statistics...though the amount of tree memory as reported by
> dump_tree_statistics is somewhat suspect, since it doesn't include
> statistics from copy_node_stat.

I thought I had fixed that ... but appearantly I didn't commit that part.

> The patch series has been bootstrapped on x86_64-unknown-linux-gnu, both
> in its entirety and with sub-patches along the way.  Indeed, the patches
> were not developed in this order; the checking bits were introduced
> first, then any bootstrap or testsuite failures were fixed up, then the
> patches were committed in the proper order.

Did you make sure to enable all languages?  And grep for occurances in
backends?

Thanks,
Richard.

> Nathan Froyd (18):
>  add typed_tree structure
>  enforce TREE_CHAIN and TREE_TYPE accesses
>  remove TREE_CHAIN from *_CST nodes
>  remove TREE_CHAIN from SSA_NAME nodes
>  remove TREE_CHAIN from CONSTRUCTOR nodes
>  define CASE_CHAIN accessor for CASE_LABEL_EXPR
>  generalize build_case_label to the rest of the compiler
>  convert cp *FOR_STMTs to use private scope fields
>  convert cp IF_STMTs to use private scope fields
>  convert cp SWITCH_STMTs to use private scope fields
>  mark EXPR_PACK_EXPANSION as typed only
>  make CASE_LABEL_EXPR not abuse TREE_CHAIN
>  move TS_EXP to be a substructure of TS_TYPED
>  move TS_STATEMENT_LIST to be a substructure of TS_TYPED
>  move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier
>  make TS_IDENTIFIER be a substructure of TS_BASE
>  introduce block_chainon and use BLOCK_CHAIN more
>  make TS_BLOCK a substructure of TS_BASE
>
>  gcc/ada/gcc-interface/ada-tree.h |    2 +-
>  gcc/ada/gcc-interface/misc.c     |   16 ++++++
>  gcc/ada/gcc-interface/trans.c    |    5 +-
>  gcc/ada/gcc-interface/utils.c    |    4 +-
>  gcc/c-decl.c                     |    8 ++-
>  gcc/c-family/c-common.c          |   14 +++++-
>  gcc/c-family/c-common.h          |   20 +++++---
>  gcc/c-family/c-semantics.c       |   28 ++++-------
>  gcc/c-lang.c                     |    2 +
>  gcc/c-parser.c                   |    2 +-
>  gcc/c-typeck.c                   |    2 +-
>  gcc/cp/cp-lang.c                 |   22 +--------
>  gcc/cp/cp-objcp-common.c         |   74 +++++++++++++++++++++++++++
>  gcc/cp/cp-objcp-common.h         |    1 +
>  gcc/cp/cp-tree.def               |   19 ++++---
>  gcc/cp/cp-tree.h                 |   43 ++++++++++------
>  gcc/cp/decl.c                    |   28 ++++++----
>  gcc/cp/decl2.c                   |   20 ++++---
>  gcc/cp/error.c                   |    2 +-
>  gcc/cp/init.c                    |    6 +-
>  gcc/cp/mangle.c                  |   28 +++++++---
>  gcc/cp/name-lookup.c             |   10 ++--
>  gcc/cp/pt.c                      |   40 +++++++++------
>  gcc/cp/repo.c                    |    2 +-
>  gcc/cp/rtti.c                    |    6 +-
>  gcc/cp/search.c                  |    4 +-
>  gcc/cp/semantics.c               |   41 +++++++++------
>  gcc/cp/typeck.c                  |    4 +-
>  gcc/except.c                     |    5 +-
>  gcc/fortran/f95-lang.c           |    8 ++--
>  gcc/fortran/trans-decl.c         |    2 +-
>  gcc/fortran/trans-io.c           |    2 +-
>  gcc/fortran/trans-stmt.c         |   14 ++---
>  gcc/function.c                   |   28 ++++++++++
>  gcc/function.h                   |    1 +
>  gcc/gimplify.c                   |   14 +++---
>  gcc/go/go-lang.c                 |    2 +-
>  gcc/java/decl.c                  |   13 ++---
>  gcc/java/expr.c                  |    9 ++--
>  gcc/java/java-tree.h             |    2 +-
>  gcc/lto-streamer-in.c            |    2 +-
>  gcc/lto-streamer-out.c           |    2 +-
>  gcc/lto-streamer.c               |    1 +
>  gcc/lto/lto-tree.h               |    2 +-
>  gcc/lto/lto.c                    |    3 +-
>  gcc/objc/objc-act.c              |   18 +++++++
>  gcc/objc/objc-act.h              |    1 +
>  gcc/objc/objc-lang.c             |   32 +-----------
>  gcc/objcp/objcp-lang.c           |   48 +-----------------
>  gcc/omp-low.c                    |    7 +--
>  gcc/print-tree.c                 |   11 +---
>  gcc/tree-cfg.c                   |   12 ++--
>  gcc/tree-eh.c                    |   22 +++-----
>  gcc/tree-flow.h                  |    2 +-
>  gcc/tree-inline.c                |    3 +-
>  gcc/tree-iterator.c              |   17 ++----
>  gcc/tree-ssanames.c              |   28 +++-------
>  gcc/tree.c                       |   96 ++++++++++++-----------------------
>  gcc/tree.def                     |    2 +-
>  gcc/tree.h                       |  103 +++++++++++++++++++++++++++++--------
>  gcc/treestruct.def               |    1 +
>  gcc/varasm.c                     |    1 -
>  62 files changed, 535 insertions(+), 432 deletions(-)
>
>

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

* Re: [4.7 PATCH 00/18] slim down a number of tree nodes
  2011-03-11 13:25 ` Richard Guenther
@ 2011-03-11 13:42   ` Nathan Froyd
  0 siblings, 0 replies; 20+ messages in thread
From: Nathan Froyd @ 2011-03-11 13:42 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches, fortran, java-patches

On Fri, Mar 11, 2011 at 02:25:38PM +0100, Richard Guenther wrote:
> On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> > This patch series does something similar to what:
> >
> > http://gcc.gnu.org/ml/gcc-patches/2010-11/msg02491.html
> >
> > did, only it does it in a cleaner way and it addresses the problem more
> > generally.
> >
> > Eliminating the block field from tree_exp would be another nice-to-have
> > for 4.7, but that's not on my radar of things to address at the moment.
> 
> I think removing TREE_TYPE from tree_exp isn't worth it, we do not have
> many expression trees left with tuples.  Unifying BLOCK with locations
> would indeed be nice (but again we don't have many exp trees left).

Well, the patch from last November showed that there are enough
expressions left that eliminating a pointer reduces GC memory by ~1%.
So I'd say shrinking things would still be worthwhile.

> > I have not rigorously measured memory savings with this patch.  Based on
> > a (very small) sample, this patch saves ~5% of tree memory according to
> > dump_tree_statistics...though the amount of tree memory as reported by
> > dump_tree_statistics is somewhat suspect, since it doesn't include
> > statistics from copy_node_stat.
> 
> I thought I had fixed that ... but appearantly I didn't commit that
> part.

I have a patch which I will submit for 4.7, so unless you beat me to
it...

> > The patch series has been bootstrapped on x86_64-unknown-linux-gnu, both
> > in its entirety and with sub-patches along the way.
> 
> Did you make sure to enable all languages?  And grep for occurances in
> backends?

I bootstrapped with
--enable-languages=c,c++,ada,fortran,java,objc,obj-c++,go.  I didn't
check for bits in the backends; I can look around, but any backend
poking in the fields that got eliminated deserves what's coming.

-Nathan

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

* Re: [PATCH 07/18] generalize build_case_label to the rest of the compiler
  2011-03-11  4:30 ` [PATCH 07/18] generalize build_case_label to the rest of the compiler Nathan Froyd
  2011-03-11 13:01   ` Joseph S. Myers
@ 2011-03-11 14:56   ` Tom Tromey
  1 sibling, 0 replies; 20+ messages in thread
From: Tom Tromey @ 2011-03-11 14:56 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, fortran, java-patches

>>>>> "Nathan" == Nathan Froyd <froydnj@codesourcery.com> writes:

Nathan> gcc/java/
Nathan> 	* expr.c (expand_java_switch): Call build_case_label.
Nathan> 	(expand_java_add_case): Likewise.

The java parts are ok.

FWIW, I tend to think that if a core change like this one is accepted,
then updates to the front ends should be considered obvious, barring
some unusual circumstance.

Your update to this patch to pass a location, per the other reviews, is
pre-approved.

Tom

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

* Re: [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more
  2011-03-11  4:24 ` [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more Nathan Froyd
  2011-03-11 13:15   ` Richard Guenther
@ 2011-03-11 15:14   ` Tom Tromey
  2011-03-12 12:23   ` Eric Botcazou
  2 siblings, 0 replies; 20+ messages in thread
From: Tom Tromey @ 2011-03-11 15:14 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, fortran, java-patches

>>>>> "Nathan" == Nathan Froyd <froydnj@codesourcery.com> writes:

Nathan> gcc/java/
Nathan> 	* decl.c (poplevel): Use BLOCK_CHAIN and block_chainon.

This is ok.

Tom

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

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-11  4:30 ` [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses Nathan Froyd
  2011-03-11  8:12   ` Mike Stump
  2011-03-11 13:21   ` Richard Guenther
@ 2011-03-11 15:24   ` Tom Tromey
  2011-03-12 12:13   ` Eric Botcazou
  3 siblings, 0 replies; 20+ messages in thread
From: Tom Tromey @ 2011-03-11 15:24 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, fortran, java-patches

>>>>> "Nathan" == Nathan Froyd <froydnj@codesourcery.com> writes:

Nathan> gcc/java/
Nathan> 	* java-tree.h (union lang_tree_node): Check for TS_COMMON before
Nathan> 	calling TREE_CHAIN.

This is ok.

Tom

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

* Re: [4.7 PATCH 00/18] slim down a number of tree nodes
  2011-03-11  8:18 ` [4.7 PATCH 00/18] slim down a number of tree nodes Mike Stump
@ 2011-03-11 16:00   ` Nathan Froyd
  0 siblings, 0 replies; 20+ messages in thread
From: Nathan Froyd @ 2011-03-11 16:00 UTC (permalink / raw)
  To: Mike Stump; +Cc: gcc-patches, fortran, java-patches

On Fri, Mar 11, 2011 at 12:18:15AM -0800, Mike Stump wrote:
> On Mar 10, 2011, at 8:23 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> > This patch series does something similar to what
> 
> I am curious what the speed differences are.

A non-rigorous, C-only, release-checking bootstrap (which showed me that
I forgot to change the release-checking TREE_TYPE macro, oops!) make -j4
on a lightly-loaded-ish quad-core machine gave these numbers:

without patch
real    10m8.397s
user    33m18.060s
sys     2m43.300s

with patch
real 9m57.203s
user 33m12.660s
sys  2m44.090s

So noise-ish territory.  I suppose a more fair comparison would be just
the gcc/ directory, and those non-rigorous numbers, from a 'cd gcc &&
make && time make -j4' post-bootstrap are:

without patch gcc/
real    2m41.307s
user    8m0.180s
sys     0m30.950s

with patch gcc/
real 2m35.716s
user 7m55.050s
sys  0m30.160s

Of course, these numbers were only measured once, so they are
non-definitive, etc. etc.

-Nathan

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

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-11  4:30 ` [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses Nathan Froyd
                     ` (2 preceding siblings ...)
  2011-03-11 15:24   ` Tom Tromey
@ 2011-03-12 12:13   ` Eric Botcazou
  3 siblings, 0 replies; 20+ messages in thread
From: Eric Botcazou @ 2011-03-12 12:13 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, fortran, java-patches

> gcc/ada/
> 	* gcc-interface/ada-tree.h (union lang_tree_node): Check for
> 	TS_COMMON before calling TREE_CHAIN.
> 	* gcc-interface/misc.c (gnat_init_ts): New function.
> 	(LANG_HOOKS_INIT_TS): Define.

I presume that PLUS_NOMOD_EXPR, MINUS_NOMOD_EXPR and ATTR_ADDR_EXPR need not 
be marked in gnat_init_ts?  If so, please add a single comment to that effect 
in the function and reorder the lines to match the order in ada-tree.def.

OK with these changes.

-- 
Eric Botcazou

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

* Re: [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more
  2011-03-11  4:24 ` [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more Nathan Froyd
  2011-03-11 13:15   ` Richard Guenther
  2011-03-11 15:14   ` Tom Tromey
@ 2011-03-12 12:23   ` Eric Botcazou
  2 siblings, 0 replies; 20+ messages in thread
From: Eric Botcazou @ 2011-03-12 12:23 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, fortran, java-patches

> gcc/ada/
> 	* gcc-interface/utils.c (gnat_poplevel): Use block_chainon.

OK, thanks.

-- 
Eric Botcazou

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

end of thread, other threads:[~2011-03-12 12:23 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
2011-03-11  4:24 ` [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more Nathan Froyd
2011-03-11 13:15   ` Richard Guenther
2011-03-11 13:19     ` Nathan Froyd
2011-03-11 15:14   ` Tom Tromey
2011-03-12 12:23   ` Eric Botcazou
2011-03-11  4:30 ` [PATCH 07/18] generalize build_case_label to the rest of the compiler Nathan Froyd
2011-03-11 13:01   ` Joseph S. Myers
2011-03-11 13:10     ` Richard Guenther
2011-03-11 14:56   ` Tom Tromey
2011-03-11  4:30 ` [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses Nathan Froyd
2011-03-11  8:12   ` Mike Stump
2011-03-11 13:21   ` Richard Guenther
2011-03-11 15:24   ` Tom Tromey
2011-03-12 12:13   ` Eric Botcazou
2011-03-11  8:18 ` [4.7 PATCH 00/18] slim down a number of tree nodes Mike Stump
2011-03-11 16:00   ` Nathan Froyd
2011-03-11  9:38 ` Andrew Haley
2011-03-11 13:25 ` Richard Guenther
2011-03-11 13:42   ` Nathan Froyd

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).