public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 05/18] remove TREE_CHAIN from CONSTRUCTOR nodes
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
  2011-03-11  4:23 ` [PATCH 04/18] remove TREE_CHAIN from SSA_NAME nodes Nathan Froyd
@ 2011-03-11  4:23 ` Nathan Froyd
  2011-03-11 13:05   ` Richard Guenther
  2011-03-11  4:24 ` [PATCH 14/18] move TS_STATEMENT_LIST to be a substructure of TS_TYPED Nathan Froyd
                   ` (17 subsequent siblings)
  19 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:23 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

A straightforward conversion.

-Nathan

gcc/
	* tree.h (struct tree_constructor): Include typed_tree instead of
	tree_common.
	* tree.c (initialize_tree_contains_struct): Mark TS_CONSTRUCTOR as
	TS_TYPED instead of TS_COMMON.

diff --git a/gcc/tree.c b/gcc/tree.c
index 072ff19..da16641 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -377,6 +377,7 @@ initialize_tree_contains_struct (void)
 	case TS_STRING:
 	case TS_COMPLEX:
 	case TS_SSA_NAME:
+	case TS_CONSTRUCTOR:
 	  MARK_TS_TYPED (code);
 	  break;
 
@@ -389,7 +390,6 @@ initialize_tree_contains_struct (void)
 	case TS_BLOCK:
 	case TS_BINFO:
 	case TS_STATEMENT_LIST:
-	case TS_CONSTRUCTOR:
 	case TS_OMP_CLAUSE:
 	case TS_OPTIMIZATION:
 	case TS_TARGET_OPTION:
diff --git a/gcc/tree.h b/gcc/tree.h
index 80888bc..35479f9 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1614,7 +1614,7 @@ DEF_VEC_O(constructor_elt);
 DEF_VEC_ALLOC_O(constructor_elt,gc);
 
 struct GTY(()) tree_constructor {
-  struct tree_common common;
+  struct typed_tree typed;
   VEC(constructor_elt,gc) *elts;
 };
 
-- 
1.7.0.4

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

* [4.7 PATCH 00/18] slim down a number of tree nodes
@ 2011-03-11  4:23 Nathan Froyd
  2011-03-11  4:23 ` [PATCH 04/18] remove TREE_CHAIN from SSA_NAME nodes Nathan Froyd
                   ` (19 more replies)
  0 siblings, 20 replies; 68+ 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] 68+ messages in thread

* [PATCH 04/18] remove TREE_CHAIN from SSA_NAME nodes
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
@ 2011-03-11  4:23 ` Nathan Froyd
  2011-03-11 13:06   ` Richard Guenther
  2011-03-11  4:23 ` [PATCH 05/18] remove TREE_CHAIN from CONSTRUCTOR nodes Nathan Froyd
                   ` (18 subsequent siblings)
  19 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:23 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

This conversion is straightforward.  The tricky part is converting
FREE_SSANAMES into a VEC to eliminate the only use of TREE_CHAIN on
SSA_NAMEs.

-Nathan

gcc/
	* tree-flow.h (struct gimple_df): Make free_ssanames a VEC.
	* tree-ssanames.c (fini_ssanames): VEC_free it.
	(make_ssa_name_fn): Update for VECness of free_ssanames.
	(release_ssa_name, release_dead_ssa_names): Likewise.
	* tree.h (struct tree_ssa_name): Include typed_tree instead of
	tree_common.
	* tree.c (initialize_tree_contains_struct): Mark TS_SSA_NAME as
	TS_TYPED instead of TS_COMMON.

diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 14c8827..6b48697 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -61,7 +61,7 @@ struct GTY(()) gimple_df {
   struct pointer_map_t * GTY((skip(""))) decls_to_pointers;
 
   /* Free list of SSA_NAMEs.  */
-  tree free_ssanames;
+  VEC(tree,gc) *free_ssanames;
 
   /* Hashtable holding definition for symbol.  If this field is not NULL, it
      means that the first reference to this variable in the function is a
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index c76dba5..06cdbee 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -96,7 +96,7 @@ void
 fini_ssanames (void)
 {
   VEC_free (tree, gc, SSANAMES (cfun));
-  FREE_SSANAMES (cfun) = NULL;
+  VEC_free (tree, gc, FREE_SSANAMES (cfun));
 }
 
 /* Dump some simple statistics regarding the re-use of SSA_NAME nodes.  */
@@ -124,10 +124,9 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
   gcc_assert (DECL_P (var));
 
   /* If our free list has an element, then use it.  */
-  if (FREE_SSANAMES (fn))
+  if (!VEC_empty (tree, FREE_SSANAMES (fn)))
     {
-      t = FREE_SSANAMES (fn);
-      FREE_SSANAMES (fn) = TREE_CHAIN (FREE_SSANAMES (fn));
+      t = VEC_pop (tree, FREE_SSANAMES (fn));
 #ifdef GATHER_STATISTICS
       ssa_name_nodes_reused++;
 #endif
@@ -234,9 +233,8 @@ release_ssa_name (tree var)
       /* Note this SSA_NAME is now in the first list.  */
       SSA_NAME_IN_FREE_LIST (var) = 1;
 
-      /* And finally link it into the free list.  */
-      TREE_CHAIN (var) = FREE_SSANAMES (cfun);
-      FREE_SSANAMES (cfun) = var;
+      /* And finally put it on the free list.  */
+      VEC_safe_push (tree, gc, FREE_SSANAMES (cfun), var);
     }
 }
 
@@ -334,8 +332,8 @@ replace_ssa_name_symbol (tree ssa_name, tree sym)
 static unsigned int
 release_dead_ssa_names (void)
 {
-  tree t, next;
-  int n = 0;
+  tree t;
+  int n = VEC_length (tree, FREE_SSANAMES (cfun));
   referenced_var_iterator rvi;
 
   /* Current defs point to various dead SSA names that in turn point to
@@ -343,17 +341,7 @@ release_dead_ssa_names (void)
   FOR_EACH_REFERENCED_VAR (cfun, t, rvi)
     set_current_def (t, NULL);
   /* Now release the freelist.  */
-  for (t = FREE_SSANAMES (cfun); t; t = next)
-    {
-      next = TREE_CHAIN (t);
-      /* Dangling pointers might make GGC to still see dead SSA names, so it is
- 	 important to unlink the list and avoid GGC from seeing all subsequent
-	 SSA names.  In longer run we want to have all dangling pointers here
-	 removed (since they usually go through dead statements that consume
-	 considerable amounts of memory).  */
-      TREE_CHAIN (t) = NULL_TREE;
-      n++;
-    }
+  VEC_free (tree, gc, FREE_SSANAMES (cfun));
   FREE_SSANAMES (cfun) = NULL;
 
   statistics_counter_event (cfun, "SSA names released", n);
diff --git a/gcc/tree.c b/gcc/tree.c
index 7d73c74..072ff19 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -376,6 +376,7 @@ initialize_tree_contains_struct (void)
 	case TS_VECTOR:
 	case TS_STRING:
 	case TS_COMPLEX:
+	case TS_SSA_NAME:
 	  MARK_TS_TYPED (code);
 	  break;
 
@@ -385,7 +386,6 @@ initialize_tree_contains_struct (void)
 	case TS_LIST:
 	case TS_VEC:
 	case TS_EXP:
-	case TS_SSA_NAME:
 	case TS_BLOCK:
 	case TS_BINFO:
 	case TS_STATEMENT_LIST:
diff --git a/gcc/tree.h b/gcc/tree.h
index 11c2f83..80888bc 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1970,7 +1970,7 @@ typedef struct GTY(()) ssa_use_operand_d {
 #define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses
 
 struct GTY(()) tree_ssa_name {
-  struct tree_common common;
+  struct typed_tree typed;
 
   /* _DECL wrapped by this SSA name.  */
   tree var;
-- 
1.7.0.4

^ permalink raw reply	[flat|nested] 68+ 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
                   ` (3 preceding siblings ...)
  2011-03-11  4:24 ` [PATCH 03/18] remove TREE_CHAIN from *_CST nodes Nathan Froyd
@ 2011-03-11  4:24 ` Nathan Froyd
  2011-03-11 13:01   ` Joseph S. Myers
  2011-03-11 14:56   ` Tom Tromey
  2011-03-11  4:24 ` [PATCH 16/18] make TS_IDENTIFIER be a substructure of TS_BASE Nathan Froyd
                   ` (14 subsequent siblings)
  19 siblings, 2 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:24 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] 68+ messages in thread

* [PATCH 14/18] move TS_STATEMENT_LIST to be a substructure of TS_TYPED
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
  2011-03-11  4:23 ` [PATCH 04/18] remove TREE_CHAIN from SSA_NAME nodes Nathan Froyd
  2011-03-11  4:23 ` [PATCH 05/18] remove TREE_CHAIN from CONSTRUCTOR nodes Nathan Froyd
@ 2011-03-11  4:24 ` Nathan Froyd
  2011-03-11  6:01   ` Jason Merrill
  2011-03-11  4:24 ` [PATCH 03/18] remove TREE_CHAIN from *_CST nodes Nathan Froyd
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd, jason

STATEMENT_LISTs use TREE_CHAIN for approximately nothing, so let's try
to shrink them.  This patch involves quite a bit of refactoring in the C
and C++ FEs, as they used TREE_CHAIN to hold a stack of STATEMENT_LISTs
being built.  Most of the noise comes from unifying the checking macro
name between the C FE and the C++ FE.  The new checks in add_stmt are
required to make sure that cur_stmt_list can always point at something
when calling append_to_statement_list_force.

I would have liked to remove TREE_TYPE, too; I tried, but doing so was
leading to lots of ugly hacks, so I postponed that for a different day.

-Nathan

gcc/
	* c-decl.c (c_push_function_context): Copy the current statement
	list stack.
	(add_stmt): Check building_stmt_list_p and push_stmt if necessary.
	(finish_struct): Call building_stmt_list_p instead of checking
	cur_stmt_list.
	* c-parser.c (c_parser_postfix_expression): Likewise.
	* c-typeck.c (c_end_compound_stmt): Likewise.
	* print-tree.c (print_node) [STATEMENT_LIST]: Don't print TREE_CHAIN.
	* tree-iterator.c (stmt_list_cache): Change to a VEC.
	(alloc_stmt_list): Adjust for stmt_list_cache's new type.
	(free_stmt_list): Likewise.
	* tree.h (struct tree_statement_list): Include typed_tree instead
	of tree_common.
	* tree.c (initialize_tree_contains_struct): Mark TS_STATEMENT_LIST
	as TS_TYPED instead of TS_COMMON.

gcc/c-family/
	* c-common.h (struct stmt_tree_s) [x_cur_stmt_list]: Change to a VEC.
	(stmt_list_stack): Define.
	(cur_stmt_list): Adjust for new type of x_cur_stmt_list.
	* c-semantics.c (push_stmt_list, pop_stmt_list): Likewise.

gcc/cp/
	* cp-tree.h (building_stmt_tree): Delete.
	* decl.c (save_function_data): Tweak initializer for x_cur_stmt_list.
	(build_aggr_init_full_exprs): Call building_stmt_list_p
	instead of building_stmt_tree.
	(initialize_local_var): Likewise.
	(finish_function): Likewise.
	* decl2.c (finish_anon_union): Likewise.
	* init.c (begin_init_stmts): Likewise.
	(finish_init_stmts): Likewise.
	(expand_aggr_init_1): Likewise.
	* name-lookup.c (do_local_using_decl): Likewise.
	(do_namespace_alias): Likewise.
	(do_using_directive): Likewise.
	(cp_emit_debug_info_for_using): Likewise.
	* semantics.c (add_stmt): Check building_stmt_list_p and push_stmt
	if necessary.

diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 14aef5f..9b87608 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -556,6 +556,8 @@ add_stmt (tree t)
 
   /* Add T to the statement-tree.  Non-side-effect statements need to be
      recorded during statement expressions.  */
+  if (!building_stmt_list_p ())
+    push_stmt_list ();
   append_to_statement_list_force (t, &cur_stmt_list);
 
   return t;
@@ -7213,7 +7215,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
   /* If we're inside a function proper, i.e. not file-scope and not still
      parsing parameters, then arrange for the size of a variable sized type
      to be bound now.  */
-  if (cur_stmt_list && variably_modified_type_p (t, NULL_TREE))
+  if (building_stmt_list_p () && variably_modified_type_p (t, NULL_TREE))
     add_stmt (build_stmt (loc,
 			  DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)));
 
@@ -8461,6 +8463,8 @@ c_push_function_context (void)
   cfun->language = p;
 
   p->base.x_stmt_tree = c_stmt_tree;
+  c_stmt_tree.x_cur_stmt_list
+    = VEC_copy (tree, gc, c_stmt_tree.x_cur_stmt_list);
   p->x_break_label = c_break_label;
   p->x_cont_label = c_cont_label;
   p->x_switch_stack = c_switch_stack;
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 382d535..e7fe209 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -451,8 +451,8 @@ typedef enum ref_operator {
 /* Information about a statement tree.  */
 
 struct GTY(()) stmt_tree_s {
-  /* The current statement list being collected.  */
-  tree x_cur_stmt_list;
+  /* A stack of statement lists being collected.  */
+  VEC(tree,gc) *x_cur_stmt_list;
 
   /* In C++, Nonzero if we should treat statements as full
      expressions.  In particular, this variable is no-zero if at the
@@ -482,11 +482,17 @@ struct GTY(()) c_language_function {
   struct stmt_tree_s x_stmt_tree;
 };
 
+#define stmt_list_stack (current_stmt_tree ()->x_cur_stmt_list)
+
 /* When building a statement-tree, this is the current statement list
-   being collected.  It's TREE_CHAIN is a back-pointer to the previous
-   statement list.  */
+   being collected.  We define it in this convoluted way, rather than
+   using VEC_last, because it must be an lvalue.  */
+
+#define cur_stmt_list							\
+  (*(VEC_address (tree, stmt_list_stack)				\
+     + VEC_length (tree, stmt_list_stack) - 1))
 
-#define cur_stmt_list (current_stmt_tree ()->x_cur_stmt_list)
+#define building_stmt_list_p() (!VEC_empty (tree, stmt_list_stack))
 
 /* Language-specific hooks.  */
 
diff --git a/gcc/c-family/c-semantics.c b/gcc/c-family/c-semantics.c
index a5bd9ba..cb0f2be 100644
--- a/gcc/c-family/c-semantics.c
+++ b/gcc/c-family/c-semantics.c
@@ -38,8 +38,7 @@ push_stmt_list (void)
 {
   tree t;
   t = alloc_stmt_list ();
-  TREE_CHAIN (t) = cur_stmt_list;
-  cur_stmt_list = t;
+  VEC_safe_push (tree, gc, stmt_list_stack, t);
   return t;
 }
 
@@ -48,21 +47,23 @@ push_stmt_list (void)
 tree
 pop_stmt_list (tree t)
 {
-  tree u = cur_stmt_list, chain;
+  tree u = NULL_TREE;
 
   /* Pop statement lists until we reach the target level.  The extra
      nestings will be due to outstanding cleanups.  */
   while (1)
     {
-      chain = TREE_CHAIN (u);
-      TREE_CHAIN (u) = NULL_TREE;
-      if (chain)
-	STATEMENT_LIST_HAS_LABEL (chain) |= STATEMENT_LIST_HAS_LABEL (u);
+      u = VEC_pop (tree, stmt_list_stack);
+      if (!VEC_empty (tree, stmt_list_stack))
+	{
+	  tree x = VEC_last (tree, stmt_list_stack);
+	  STATEMENT_LIST_HAS_LABEL (x) |= STATEMENT_LIST_HAS_LABEL (u);
+	}
       if (t == u)
 	break;
-      u = chain;
     }
-  cur_stmt_list = chain;
+
+  gcc_assert (u != NULL_TREE);
 
   /* If the statement list is completely empty, just return it.  This is
      just as good small as build_empty_stmt, with the advantage that
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 69ce2e5..7580441 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -6107,7 +6107,7 @@ c_parser_postfix_expression (c_parser *parser)
 	  c_parser_consume_token (parser);
 	  brace_loc = c_parser_peek_token (parser)->location;
 	  c_parser_consume_token (parser);
-	  if (cur_stmt_list == NULL)
+	  if (!building_stmt_list_p ())
 	    {
 	      error_at (loc, "braced-group within expression allowed "
 			"only inside a function");
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index a22bb73..c42f118 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -9284,7 +9284,7 @@ c_end_compound_stmt (location_t loc, tree stmt, bool do_scope)
      do the wrong thing for ({ { 1; } }) or ({ 1; { } }).  In particular,
      STATEMENT_LISTs merge, and thus we can lose track of what statement
      was really last.  */
-  if (cur_stmt_list
+  if (building_stmt_list_p ()
       && STATEMENT_LIST_STMT_EXPR (cur_stmt_list)
       && TREE_CODE (stmt) != BIND_EXPR)
     {
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 7bdf9e0..fd28593 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -292,10 +292,6 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
 #define same_type_p(TYPE1, TYPE2) \
   comptypes ((TYPE1), (TYPE2), COMPARE_STRICT)
 
-/* Nonzero if we are presently building a statement tree, rather
-   than expanding each statement as we encounter it.  */
-#define building_stmt_tree()  (cur_stmt_list != NULL_TREE)
-
 /* Returns nonzero iff NODE is a declaration for the global function
    `main'.  */
 #define DECL_MAIN_P(NODE)				\
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 6ff6974..e1e6fe2 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5245,13 +5245,13 @@ build_aggr_init_full_exprs (tree decl, tree init, int flags)
      
 {
   int saved_stmts_are_full_exprs_p = 0;
-  if (building_stmt_tree ())
+  if (building_stmt_list_p ())
     {
       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
       current_stmt_tree ()->stmts_are_full_exprs_p = 1;
     }
   init = build_aggr_init (decl, init, flags, tf_warning_or_error);
-  if (building_stmt_tree ())
+  if (building_stmt_list_p ())
     current_stmt_tree ()->stmts_are_full_exprs_p =
       saved_stmts_are_full_exprs_p;
   return init;
@@ -5633,7 +5633,7 @@ initialize_local_var (tree decl, tree init)
       if (cleanup && TREE_CODE (type) != ARRAY_TYPE)
 	wrap_temporary_cleanups (init, cleanup);
 
-      gcc_assert (building_stmt_tree ());
+      gcc_assert (building_stmt_list_p ());
       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
       current_stmt_tree ()->stmts_are_full_exprs_p = 1;
       finish_expr_stmt (init);
@@ -12609,7 +12609,7 @@ save_function_data (tree decl)
   DECL_SAVED_FUNCTION_DATA (decl) = f;
 
   /* Clear out the bits we don't need.  */
-  f->base.x_stmt_tree.x_cur_stmt_list = NULL_TREE;
+  f->base.x_stmt_tree.x_cur_stmt_list = NULL;
   f->bindings = NULL;
   f->x_local_names = NULL;
 }
@@ -12854,7 +12854,7 @@ finish_function (int flags)
       This caused &foo to be of type ptr-to-const-function
       which then got a warning when stored in a ptr-to-function variable.  */
 
-  gcc_assert (building_stmt_tree ());
+  gcc_assert (building_stmt_list_p ());
   /* The current function is being defined, so its DECL_INITIAL should
      be set, and unless there's a multiple definition, it should be
      error_mark_node.  */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 93d44a4..fa114ba 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1415,7 +1415,7 @@ finish_anon_union (tree anon_union_decl)
     }
 
   pushdecl (anon_union_decl);
-  if (building_stmt_tree ()
+  if (building_stmt_list_p ()
       && at_function_scope_p ())
     add_decl_expr (anon_union_decl);
   else if (!processing_template_decl)
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index e590118..f2173a4 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -64,7 +64,7 @@ static int diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool, bool);
 static bool
 begin_init_stmts (tree *stmt_expr_p, tree *compound_stmt_p)
 {
-  bool is_global = !building_stmt_tree ();
+  bool is_global = !building_stmt_list_p ();
 
   *stmt_expr_p = begin_stmt_expr ();
   *compound_stmt_p = begin_compound_stmt (BCS_NO_SCOPE);
@@ -82,7 +82,7 @@ finish_init_stmts (bool is_global, tree stmt_expr, tree compound_stmt)
 
   stmt_expr = finish_stmt_expr (stmt_expr, true);
 
-  gcc_assert (!building_stmt_tree () == is_global);
+  gcc_assert (!building_stmt_list_p () == is_global);
 
   return stmt_expr;
 }
@@ -1491,7 +1491,7 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
   tree type = TREE_TYPE (exp);
 
   gcc_assert (init != error_mark_node && type != error_mark_node);
-  gcc_assert (building_stmt_tree ());
+  gcc_assert (building_stmt_list_p ());
 
   /* Use a function returning the desired type to initialize EXP for us.
      If the function is a constructor, and its first argument is
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index e2e5450..b5472de 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2392,7 +2392,7 @@ do_local_using_decl (tree decl, tree scope, tree name)
   if (decl == NULL_TREE)
     return;
 
-  if (building_stmt_tree ()
+  if (building_stmt_list_p ()
       && at_function_scope_p ())
     add_decl_expr (decl);
 
@@ -3439,7 +3439,7 @@ do_namespace_alias (tree alias, tree name_space)
   pushdecl (alias);
 
   /* Emit debug info for namespace alias.  */
-  if (!building_stmt_tree ())
+  if (!building_stmt_list_p ())
     (*debug_hooks->global_decl) (alias);
 }
 
@@ -3581,7 +3581,7 @@ do_using_directive (tree name_space)
 
   gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
 
-  if (building_stmt_tree ())
+  if (building_stmt_list_p ())
     add_stmt (build_stmt (input_location, USING_STMT, name_space));
   name_space = ORIGINAL_NAMESPACE (name_space);
 
@@ -5647,7 +5647,7 @@ cp_emit_debug_info_for_using (tree t, tree context)
   for (t = OVL_CURRENT (t); t; t = OVL_NEXT (t))
     if (TREE_CODE (t) != TEMPLATE_DECL)
       {
-	if (building_stmt_tree ())
+	if (building_stmt_list_p ())
 	  add_stmt (build_stmt (input_location, USING_STMT, t));
 	else
 	  (*debug_hooks->imported_module_or_decl) (t, NULL_TREE, context, false);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 689ad00..6c8dfd7 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -393,6 +393,8 @@ add_stmt (tree t)
 
   /* Add T to the statement-tree.  Non-side-effect statements need to be
      recorded during statement expressions.  */
+  if (!building_stmt_list_p ())
+    push_stmt_list ();
   append_to_statement_list_force (t, &cur_stmt_list);
 
   return t;
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 3b5edeb..d8acd1b 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -911,7 +911,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
 		print_node (file, "stmt", tsi_stmt (i), indent + 4);
 	      }
 	  }
-	  print_node (file, "chain", TREE_CHAIN (node), indent + 4);
 	  break;
 
 	case BLOCK:
diff --git a/gcc/tree-iterator.c b/gcc/tree-iterator.c
index 05764da..44b6bed 100644
--- a/gcc/tree-iterator.c
+++ b/gcc/tree-iterator.c
@@ -31,17 +31,16 @@ along with GCC; see the file COPYING3.  If not see
 /* This is a cache of STATEMENT_LIST nodes.  We create and destroy them
    fairly often during gimplification.  */
 
-static GTY ((deletable (""))) tree stmt_list_cache;
+static GTY ((deletable (""))) VEC(tree,gc) *stmt_list_cache;
 
 tree
 alloc_stmt_list (void)
 {
-  tree list = stmt_list_cache;
-  if (list)
+  tree list;
+  if (!VEC_empty (tree, stmt_list_cache))
     {
-      stmt_list_cache = TREE_CHAIN (list);
-      gcc_assert (stmt_list_cache != list);
-      memset (list, 0, sizeof(struct tree_common));
+      list = VEC_pop (tree, stmt_list_cache);
+      memset (list, 0, sizeof(struct tree_base));
       TREE_SET_CODE (list, STATEMENT_LIST);
     }
   else
@@ -55,11 +54,7 @@ free_stmt_list (tree t)
 {
   gcc_assert (!STATEMENT_LIST_HEAD (t));
   gcc_assert (!STATEMENT_LIST_TAIL (t));
-  /* If this triggers, it's a sign that the same list is being freed
-     twice.  */
-  gcc_assert (t != stmt_list_cache || stmt_list_cache == NULL);
-  TREE_CHAIN (t) = stmt_list_cache;
-  stmt_list_cache = t;
+  VEC_safe_push (tree, gc, stmt_list_cache, t);
 }
 
 /* A subroutine of append_to_statement_list{,_force}.  T is not NULL.  */
diff --git a/gcc/tree.c b/gcc/tree.c
index 16100a6..81ee05e 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -379,6 +379,7 @@ initialize_tree_contains_struct (void)
 	case TS_SSA_NAME:
 	case TS_CONSTRUCTOR:
 	case TS_EXP:
+	case TS_STATEMENT_LIST:
 	  MARK_TS_TYPED (code);
 	  break;
 
@@ -389,7 +390,6 @@ initialize_tree_contains_struct (void)
 	case TS_VEC:
 	case TS_BLOCK:
 	case TS_BINFO:
-	case TS_STATEMENT_LIST:
 	case TS_OMP_CLAUSE:
 	case TS_OPTIMIZATION:
 	case TS_TARGET_OPTION:
diff --git a/gcc/tree.h b/gcc/tree.h
index 461674c..4e3eebd 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3514,7 +3514,7 @@ struct GTY ((chain_next ("%h.next"), chain_prev ("%h.prev"))) tree_statement_lis
 
 struct GTY(()) tree_statement_list
  {
-  struct tree_common common;
+  struct typed_tree typed;
   struct tree_statement_list_node *head;
   struct tree_statement_list_node *tail;
 };

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

* [PATCH 08/18] convert cp *FOR_STMTs to use private scope fields
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (9 preceding siblings ...)
  2011-03-11  4:24 ` [PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED Nathan Froyd
@ 2011-03-11  4:24 ` Nathan Froyd
  2011-03-11  4:24 ` [PATCH 06/18] define CASE_CHAIN accessor for CASE_LABEL_EXPR Nathan Froyd
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

C++'s FOR_STMT and RANGE_FOR_STMT store the scope in which they occur in
the TREE_CHAIN field of tree_exp.  If we're going to remove TREE_CHAIN,
that won't work very well.  This patch introduces an extra tree operand
to both tree kinds, accessor macros for those operands, and tweaks the
code to use those macros instead of TREE_CHAIN.  The end result is nicer
code and less reliance on TREE_CHAIN.

-Nathan

gcc/cp/
	* cp-tree.def (FOR_STMT, RANGE_FOR_STMT): Add an extra operand.
	* cp-objcp-common.c (cp_common_init_ts): Mark them as TS_TYPED.
	* cp-tree.h (FOR_SCOPE, RANGE_FOR_SCOPE): Define.
	* semantics.c (begin_for_stmt): Pass an extra arg to build_stmt.
	Use FOR_SCOPE instead of TREE_CHAIN.
	(begin_range_for_stmt): Likewise, with RANGE_FOR_SCOPE.
	(finish_for_stmt): Likewise.

diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 66d2d27..21fa57f 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -234,7 +234,6 @@ cp_common_init_ts (void)
   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);
@@ -245,8 +244,9 @@ cp_common_init_ts (void)
   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 (FOR_STMT);
+  MARK_TS_TYPED (RANGE_FOR_STMT);
   MARK_TS_TYPED (AGGR_INIT_EXPR);
   MARK_TS_TYPED (EXPR_STMT);
   MARK_TS_TYPED (EH_SPEC_BLOCK);
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 509d5e7..fdfe9b5 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -291,12 +291,12 @@ DEFTREECODE (IF_STMT, "if_stmt", tcc_statement, 3)
 
 /* Used to represent a `for' statement. The operands are
    FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively.  */
-DEFTREECODE (FOR_STMT, "for_stmt", tcc_statement, 4)
+DEFTREECODE (FOR_STMT, "for_stmt", tcc_statement, 5)
 
 /* Used to represent a range-based `for' statement. The operands are
-   RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY, respectively.  Only used
-   in templates.  */
-DEFTREECODE (RANGE_FOR_STMT, "range_for_stmt", tcc_statement, 3)
+   RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY, and RANGE_FOR_SCOPE,
+   respectively.  Only used in templates.  */
+DEFTREECODE (RANGE_FOR_STMT, "range_for_stmt", tcc_statement, 4)
 
 /* Used to represent a 'while' statement. The operands are WHILE_COND
    and WHILE_BODY, respectively.  */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1783915..e542388 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3799,12 +3799,14 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define FOR_COND(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 1)
 #define FOR_EXPR(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 2)
 #define FOR_BODY(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 3)
+#define FOR_SCOPE(NODE)		TREE_OPERAND (FOR_STMT_CHECK (NODE), 4)
 
 /* RANGE_FOR_STMT accessors. These give access to the declarator,
-   expression and body of the statement, respectively.  */
+   expression, body, and scope of the statement, respectively.  */
 #define RANGE_FOR_DECL(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 0)
 #define RANGE_FOR_EXPR(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 1)
 #define RANGE_FOR_BODY(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 2)
+#define RANGE_FOR_SCOPE(NODE)	TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 3)
 
 #define SWITCH_STMT_COND(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0)
 #define SWITCH_STMT_BODY(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 4af007d..c8e5619 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -856,7 +856,7 @@ begin_for_stmt (tree scope, tree init)
   tree r;
 
   r = build_stmt (input_location, FOR_STMT, NULL_TREE, NULL_TREE,
-		  NULL_TREE, NULL_TREE);
+		  NULL_TREE, NULL_TREE, NULL_TREE);
 
   if (scope == NULL_TREE)
     {
@@ -865,7 +865,7 @@ begin_for_stmt (tree scope, tree init)
 	scope = begin_for_scope (&init);
     }
   FOR_INIT_STMT (r) = init;
-  TREE_CHAIN (r) = scope;
+  FOR_SCOPE (r) = scope;
 
   return r;
 }
@@ -940,8 +940,12 @@ finish_for_stmt (tree for_stmt)
   /* Pop the scope for the body of the loop.  */
   if (flag_new_for_scope > 0)
     {
-      tree scope = TREE_CHAIN (for_stmt);
-      TREE_CHAIN (for_stmt) = NULL;
+      tree scope;
+      tree *scope_ptr = (TREE_CODE (for_stmt) == RANGE_FOR_STMT
+			 ? &RANGE_FOR_SCOPE (for_stmt)
+			 : &FOR_SCOPE (for_stmt));
+      scope = *scope_ptr;
+      *scope_ptr = NULL;
       add_stmt (do_poplevel (scope));
     }
 
@@ -959,7 +963,7 @@ begin_range_for_stmt (tree scope, tree init)
   tree r;
 
   r = build_stmt (input_location, RANGE_FOR_STMT,
-		  NULL_TREE, NULL_TREE, NULL_TREE);
+		  NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
 
   if (scope == NULL_TREE)
     {
@@ -972,7 +976,7 @@ begin_range_for_stmt (tree scope, tree init)
      pop it now.  */
   if (init)
     pop_stmt_list (init);
-  TREE_CHAIN (r) = scope;
+  RANGE_FOR_SCOPE (r) = scope;
 
   return r;
 }
-- 
1.7.0.4

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

* [PATCH 16/18] make TS_IDENTIFIER be a substructure of TS_BASE
  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  4:24 ` [PATCH 07/18] generalize build_case_label to the rest of the compiler Nathan Froyd
@ 2011-03-11  4:24 ` Nathan Froyd
  2011-03-11 13:12   ` Richard Guenther
  2011-03-11  4:24 ` [PATCH 10/18] convert cp SWITCH_STMTs to use private scope fields Nathan Froyd
                   ` (13 subsequent siblings)
  19 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

Now that we've done the requisite surgery on the C++ FE, we can
eliminate TREE_CHAIN and TREE_TYPE from IDENTIFIER_NODEs.  Doing so
turns up a couple different places that need to be tweaked.

The bit I'm not quite sure about is free_lang_data_in_decl and
find_decls_types_r.  Previously, due to C++ FE machinations, we'd free
REAL_IDENTIFIER_TYPE_VALUE naturally, through punning of TREE_TYPE.  Now
that we've shuffled that field into lang_identifier, that bit of
identifiers won't get freed...and I don't know if that causes problems.
Anybody more knowledgeable than I willing to weigh in on that?

-Nathan

gcc/
	* print-tree.c (print_node): Check for TS_TYPED structures before
	accessing TREE_TYPE.
	* tree.h (struct tree_identifier): Inherit from tree_base, not
	tree_common.
	(HT_IDENT_TO_GCC_IDENT): Adjust for said change.
	* tree.c (initialize_tree_contains_struct): Mark TS_IDENTIFIER as
	TS_BASE instead of TS_COMMON.
	(free_lang_data_in_decl): Don't set TREE_TYPE of DECL_NAME.
	(find_decls_types_r): Check for TS_TYPED structures before accessing
	TREE_TYPE.
	* varasm.c (assemble_name): Remove assert.

gcc/c-family/
	* c-common.h (struct c_common_identifier): Inherit from tree_base,
	not tree_common.

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index e7fe209..961dea7 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -306,7 +306,7 @@ enum c_tree_index
 /* Identifier part common to the C front ends.  Inherits from
    tree_identifier, despite appearances.  */
 struct GTY(()) c_common_identifier {
-  struct tree_common common;
+  struct tree_base base;
   struct cpp_hashnode node;
 };
 
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index d8acd1b..1a1e33f 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -321,7 +321,7 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
       if (indent <= 4)
 	print_node_brief (file, "type", TREE_TYPE (node), indent + 4);
     }
-  else
+  else if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
     {
       print_node (file, "type", TREE_TYPE (node), indent + 4);
       if (TREE_TYPE (node))
diff --git a/gcc/tree.c b/gcc/tree.c
index 81ee05e..001e8c8 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -366,6 +366,7 @@ initialize_tree_contains_struct (void)
       switch (ts_code)
 	{
 	case TS_TYPED:
+	case TS_IDENTIFIER:
 	  MARK_TS_BASE (code);
 	  break;
 
@@ -383,7 +384,6 @@ initialize_tree_contains_struct (void)
 	  MARK_TS_TYPED (code);
 	  break;
 
-	case TS_IDENTIFIER:
 	case TS_DECL_MINIMAL:
 	case TS_TYPE:
 	case TS_LIST:
@@ -4495,10 +4495,6 @@ free_lang_data_in_decl (tree decl)
   TREE_LANG_FLAG_5 (decl) = 0;
   TREE_LANG_FLAG_6 (decl) = 0;
 
-  /* Identifiers need not have a type.  */
-  if (DECL_NAME (decl))
-    TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;
-
   free_lang_data_in_one_sizepos (&DECL_SIZE (decl));
   free_lang_data_in_one_sizepos (&DECL_SIZE_UNIT (decl));
   if (TREE_CODE (decl) == FIELD_DECL)
@@ -4795,7 +4791,8 @@ find_decls_types_r (tree *tp, int *ws, void *data)
       fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
     }
 
-  fld_worklist_push (TREE_TYPE (t), fld);
+  if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
+    fld_worklist_push (TREE_TYPE (t), fld);
 
   return NULL_TREE;
 }
diff --git a/gcc/tree.h b/gcc/tree.h
index c81186a..f4d18f8 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1529,11 +1529,11 @@ struct GTY(()) tree_vector {
    pointer, and vice versa.  */
 
 #define HT_IDENT_TO_GCC_IDENT(NODE) \
-  ((tree) ((char *) (NODE) - sizeof (struct tree_common)))
+  ((tree) ((char *) (NODE) - sizeof (struct tree_base)))
 #define GCC_IDENT_TO_HT_IDENT(NODE) (&((struct tree_identifier *) (NODE))->id)
 
 struct GTY(()) tree_identifier {
-  struct tree_common common;
+  struct tree_base base;
   struct ht_identifier id;
 };
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 76675cd..4c429de 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2300,7 +2300,6 @@ assemble_name (FILE *file, const char *name)
       ultimate_transparent_alias_target (&id);
       if (id != id_orig)
 	name = IDENTIFIER_POINTER (id);
-      gcc_assert (! TREE_CHAIN (id));
     }
 
   assemble_name_raw (file, name);
-- 
1.7.0.4

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

* [PATCH 10/18] convert cp SWITCH_STMTs to use private scope fields
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (5 preceding siblings ...)
  2011-03-11  4:24 ` [PATCH 16/18] make TS_IDENTIFIER be a substructure of TS_BASE Nathan Froyd
@ 2011-03-11  4:24 ` Nathan Froyd
  2011-03-11  4:24 ` [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier Nathan Froyd
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

Just like the previous patches, except with SWITCH_STMT.

-Nathan

gcc/cp/
	* cp-tree.def (SWITCH_STMT): Add an extra operand.
	* cp-objcp-common.c (cp_common_init_ts): Mark it as TS_TYPED.
	* cp-tree.h (SWITCH_STMT_SCOPE): Define.
	* semantics.c (begin_switch__stmt): Pass scope to build_stmt.
	(finish_switch_stmt): Use SWITCH_STMT_SCOPE instead of TREE_CHAIN.

diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index d602dfe..57358b1 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -237,13 +237,13 @@ cp_common_init_ts (void)
   MARK_TS_COMMON (TYPENAME_TYPE);
   MARK_TS_COMMON (TYPEOF_TYPE);
   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_TYPED (SWITCH_STMT);
   MARK_TS_TYPED (IF_STMT);
   MARK_TS_TYPED (FOR_STMT);
   MARK_TS_TYPED (RANGE_FOR_STMT);
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 59f89b8..42840a8 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -313,8 +313,9 @@ DEFTREECODE (BREAK_STMT, "break_stmt", tcc_statement, 0)
 DEFTREECODE (CONTINUE_STMT, "continue_stmt", tcc_statement, 0)
 
 /* Used to represent a 'switch' statement. The operands are
-   SWITCH_STMT_COND, SWITCH_STMT_BODY and SWITCH_STMT_TYPE, respectively.  */
-DEFTREECODE (SWITCH_STMT, "switch_stmt", tcc_statement, 3)
+   SWITCH_STMT_COND, SWITCH_STMT_BODY, SWITCH_STMT_TYPE, and
+   SWITCH_STMT_SCOPE, respectively.  */
+DEFTREECODE (SWITCH_STMT, "switch_stmt", tcc_statement, 4)
 
 /* Used to represent an expression statement.  Use `EXPR_STMT_EXPR' to
    obtain the expression.  */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2340812..3249ef0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3812,6 +3812,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define SWITCH_STMT_COND(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0)
 #define SWITCH_STMT_BODY(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1)
 #define SWITCH_STMT_TYPE(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 2)
+#define SWITCH_STMT_SCOPE(NODE)	TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 3)
 
 /* STMT_EXPR accessor.  */
 #define STMT_EXPR_STMT(NODE)	TREE_OPERAND (STMT_EXPR_CHECK (NODE), 0)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 4071494..689ad00 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1018,10 +1018,9 @@ begin_switch_stmt (void)
 {
   tree r, scope;
 
-  r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
-
   scope = do_pushlevel (sk_block);
-  TREE_CHAIN (r) = scope;
+  r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE, scope);
+
   begin_cond (&SWITCH_STMT_COND (r));
 
   return r;
@@ -1077,8 +1076,8 @@ finish_switch_stmt (tree switch_stmt)
   pop_switch ();
   finish_stmt ();
 
-  scope = TREE_CHAIN (switch_stmt);
-  TREE_CHAIN (switch_stmt) = NULL;
+  scope = SWITCH_STMT_SCOPE (switch_stmt);
+  SWITCH_STMT_SCOPE (switch_stmt) = NULL;
   add_stmt (do_poplevel (scope));
 }
 
-- 
1.7.0.4

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

* [PATCH 06/18] define CASE_CHAIN accessor for CASE_LABEL_EXPR
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (10 preceding siblings ...)
  2011-03-11  4:24 ` [PATCH 08/18] convert cp *FOR_STMTs to use private scope fields Nathan Froyd
@ 2011-03-11  4:24 ` Nathan Froyd
  2011-03-11 13:07   ` Richard Guenther
  2011-03-11  4:30 ` [PATCH 11/18] mark EXPR_PACK_EXPANSION as typed only Nathan Froyd
                   ` (7 subsequent siblings)
  19 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

This patch begins a subseries of patches aimed at removing TREE_CHAIN
from expression trees.  tree-cfg.c uses TREE_CHAIN for some analysis
steps on CASE_LABEL_EXPRs.  I looked at this for a while, thinking it'd
be easy to use VECs instead, but AFAICS, it wasn't.  I went for the next
best thing, hiding TREE_CHAIN usage behind CASE_CHAIN; doing this will
enable swapping out the TREE_CHAIN for a TREE_OPERAND at a later point.

-Nathan

	* tree.h (CASE_CHAIN): Define.
	* tree-cfg.c (edge_to_cases_cleanup, get_cases_for_edge): Use it.
	(gimple_redirect_edge_and_branch): Likewise.

diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 1f533a3..bdce4cb 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -838,8 +838,8 @@ edge_to_cases_cleanup (const void *key ATTRIBUTE_UNUSED, void **value,
 
   for (t = (tree) *value; t; t = next)
     {
-      next = TREE_CHAIN (t);
-      TREE_CHAIN (t) = NULL;
+      next = CASE_CHAIN (t);
+      CASE_CHAIN (t) = NULL;
     }
 
   *value = NULL;
@@ -922,7 +922,7 @@ get_cases_for_edge (edge e, gimple t)
       /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
 	 a new chain.  */
       slot = pointer_map_insert (edge_to_cases, this_edge);
-      TREE_CHAIN (elt) = (tree) *slot;
+      CASE_CHAIN (elt) = (tree) *slot;
       *slot = elt;
     }
 
@@ -4900,7 +4900,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
 	      {
 		last = cases;
 		CASE_LABEL (cases) = label;
-		cases = TREE_CHAIN (cases);
+		cases = CASE_CHAIN (cases);
 	      }
 
 	    /* If there was already an edge in the CFG, then we need
@@ -4909,8 +4909,8 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
 	      {
 		tree cases2 = get_cases_for_edge (e2, stmt);
 
-		TREE_CHAIN (last) = TREE_CHAIN (cases2);
-		TREE_CHAIN (cases2) = first;
+		CASE_CHAIN (last) = CASE_CHAIN (cases2);
+		CASE_CHAIN (cases2) = first;
 	      }
 	    bitmap_set_bit (touched_switch_bbs, gimple_bb (stmt)->index);
 	  }
diff --git a/gcc/tree.h b/gcc/tree.h
index 35479f9..58b3b9d 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1689,6 +1689,7 @@ extern void protected_set_expr_location (tree, location_t);
 #define CASE_LOW(NODE)          	TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 0)
 #define CASE_HIGH(NODE)         	TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 1)
 #define CASE_LABEL(NODE)		TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 2)
+#define CASE_CHAIN(NODE)		TREE_CHAIN (CASE_LABEL_EXPR_CHECK (NODE))
 
 /* The operands of a TARGET_MEM_REF.  Operands 0 and 1 have to match
    corresponding MEM_REF operands.  */
-- 
1.7.0.4

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

* [PATCH 01/18] add typed_tree structure
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (7 preceding siblings ...)
  2011-03-11  4:24 ` [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier Nathan Froyd
@ 2011-03-11  4:24 ` Nathan Froyd
  2011-03-11 13:05   ` Richard Guenther
  2011-03-11 15:21   ` Michael Matz
  2011-03-11  4:24 ` [PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED Nathan Froyd
                   ` (10 subsequent siblings)
  19 siblings, 2 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

The first step in removing TREE_CHAIN (and even TREE_TYPE) from a select
few nodes is to create separate substructures for trees-with-type and
trees-with-chain.  Since trees-with-type but no chain are expected to be
more common that vice versa, make the hierarchy reflect that.  Modify a
few macros to reflect the new inheritance structure, and add a new tree
structure enum for the new structure.  Make note that we support the new
tree structure in the LTO streamer, even though we don't need to do
anything about it yet.

-Nathan

gcc/
	* tree.h (struct typed_tree): New.
	(struct tree_common): Include it instead of tree_base.
	(TREE_TYPE): Update for new location of type field.
	(TYPE_USER_ALIGN, TYPE_PACKED): Refer to base field directly.
	(DECL_USER_ALIGN, DECL_PACKED): Likewise.
	(union tree_node): Add typed field.
	* treestruct.def (TS_TYPED): New.
	* lto-streamer.c (check_handled_ts_structures): Handle it.
	* tree.c (MARK_TS_TYPED): New macro.
	(MARK_TS_COMMON): Call it instead of MARK_TS_BASE.

diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
index dba9d2d..546228c 100644
--- a/gcc/lto-streamer.c
+++ b/gcc/lto-streamer.c
@@ -270,6 +270,7 @@ check_handled_ts_structures (void)
   /* These are the TS_* structures that are either handled or
      explicitly ignored by the streamer routines.  */
   handled_p[TS_BASE] = true;
+  handled_p[TS_TYPED] = true;
   handled_p[TS_COMMON] = true;
   handled_p[TS_INT_CST] = true;
   handled_p[TS_REAL_CST] = true;
diff --git a/gcc/tree.c b/gcc/tree.c
index c947072..798bc08 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -356,9 +356,15 @@ initialize_tree_contains_struct (void)
     tree_contains_struct[C][TS_BASE] = 1;		\
   } while (0)
 
-#define MARK_TS_COMMON(C)				\
+#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)
 
diff --git a/gcc/tree.h b/gcc/tree.h
index a49e335..2f772e1 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -407,12 +407,16 @@ struct GTY(()) tree_base {
   unsigned address_space : 8;
 };
 
-struct GTY(()) tree_common {
+struct GTY(()) typed_tree {
   struct tree_base base;
-  tree chain;
   tree type;
 };
 
+struct GTY(()) tree_common {
+  struct typed_tree typed;
+  tree chain;
+};
+
 /* The following table lists the uses of each of the above flags and
    for which types of nodes they are defined.
 
@@ -869,7 +873,7 @@ enum tree_node_structure_enum {
    In VECTOR_TYPE nodes, this is the type of the elements.  */
 #define TREE_TYPE(NODE) __extension__ \
 (*({__typeof (NODE) const __t = (NODE);					\
-    &__t->common.type; }))
+    &__t->typed.type; }))
 
 extern void tree_contains_struct_check_failed (const_tree,
 					       const enum tree_node_structure_enum,
@@ -2151,7 +2155,7 @@ extern enum machine_mode vector_type_mode (const_tree);
 
 /* 1 if the alignment for this type was requested by "aligned" attribute,
    0 if it is the default for this type.  */
-#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->common.base.user_align)
+#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->base.user_align)
 
 /* The alignment for NODE, in bytes.  */
 #define TYPE_ALIGN_UNIT(NODE) (TYPE_ALIGN (NODE) / BITS_PER_UNIT)
@@ -2289,7 +2293,7 @@ extern enum machine_mode vector_type_mode (const_tree);
 
 /* Indicated that objects of this type should be laid out in as
    compact a way as possible.  */
-#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->common.base.packed_flag)
+#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->base.packed_flag)
 
 /* Used by type_contains_placeholder_p to avoid recomputation.
    Values are: 0 (unknown), 1 (false), 2 (true).  Never access
@@ -2632,7 +2636,7 @@ struct GTY(()) tree_decl_minimal {
 /* Set if the alignment of this DECL has been set by the user, for
    example with an 'aligned' attribute.  */
 #define DECL_USER_ALIGN(NODE) \
-  (DECL_COMMON_CHECK (NODE)->common.base.user_align)
+  (DECL_COMMON_CHECK (NODE)->base.user_align)
 /* Holds the machine mode corresponding to the declaration of a variable or
    field.  Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a
    FIELD_DECL.  */
@@ -2900,7 +2904,7 @@ struct GTY(()) tree_decl_with_rtl {
 #define DECL_FCONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->field_decl.fcontext)
 
 /* In a FIELD_DECL, indicates this field should be bit-packed.  */
-#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->common.base.packed_flag)
+#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->base.packed_flag)
 
 /* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed
    specially.  */
@@ -3505,6 +3509,7 @@ extern tree build_target_option_node (void);
 union GTY ((ptr_alias (union lang_tree_node),
 	    desc ("tree_node_structure (&%h)"), variable_size)) tree_node {
   struct tree_base GTY ((tag ("TS_BASE"))) base;
+  struct typed_tree GTY ((tag ("TS_TYPED"))) typed;
   struct tree_common GTY ((tag ("TS_COMMON"))) common;
   struct tree_int_cst GTY ((tag ("TS_INT_CST"))) int_cst;
   struct tree_real_cst GTY ((tag ("TS_REAL_CST"))) real_cst;
diff --git a/gcc/treestruct.def b/gcc/treestruct.def
index baea46a..b65bdc2 100644
--- a/gcc/treestruct.def
+++ b/gcc/treestruct.def
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
    specifying what structures contain what other structures in the
    tree_contains_struct array.  */
 DEFTREESTRUCT(TS_BASE, "base")
+DEFTREESTRUCT(TS_TYPED, "typed")
 DEFTREESTRUCT(TS_COMMON, "common")
 DEFTREESTRUCT(TS_INT_CST, "integer cst")
 DEFTREESTRUCT(TS_REAL_CST, "real cst")
-- 
1.7.0.4

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

* [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (6 preceding siblings ...)
  2011-03-11  4:24 ` [PATCH 10/18] convert cp SWITCH_STMTs to use private scope fields Nathan Froyd
@ 2011-03-11  4:24 ` Nathan Froyd
  2011-03-11 13:40   ` Jason Merrill
  2011-03-11  4:24 ` [PATCH 01/18] add typed_tree structure Nathan Froyd
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd, jason

IDENTIFIER_NODE is next up for a shrinking.  To do that, though, we have
to do some surgery on the C++ FE, as it uses TREE_TYPE (!) of such nodes
to store local data.  Fortunately, we can move that information into
lang_identifier; unfortunately, that means we need to introduce a number
of conditionals because the punning of TREE_TYPE no longer works.  On
the plus side, it's much more obvious where REAL_IDENTIFIER_TYPE_VALUE
was supposed to be used, as it was used inconsistently before.

I'm not overly fond of the conditionals (especially in error_operand_p)
but I don't think it's reasonable to make IDENTIFIER_NODE bigger and
penalize the other FEs just because the C++ FE is playing games with
TREE_TYPE.  I'm open to suggestions of how to avoid some of the
ugliness.  There's also one small potential problem with doing this that
I'll mention in the next patch.

-Nathan

gcc/cp/
	* cp-tree.h (struct lang_identifier): Add local_class_scope_type
	field.
	(REAL_IDENTIFIER_TYPE_VALUE): Use that field, rather than TREE_TYPE.
	(SET_IDENTIFIER_TYPE_VALUE): Use REAL_IDENTIFIER_TYPE_VALUE rather
	than TREE_TYPE.
	(error_operand_p): Make special check for IDENTIFIER_NODE.
	(DECL_CONV_FN_TYPE): Use REAL_IDENTIFIER_TYPE_VALUE.
	* decl.c (cp_finish_decl, grok_op_properties): Likewise.
	(compute_array_index_type): Check for IDENTIFIER_NODE.
	* decl2.c (constrain_visibility_for_template): Likewise.
	(determine_visibility): Use REAL_IDENTIFIER_TYPE_VALUE.
	(import_export_decl): Likewise.
	* error.c (dump_decl): Likewise.
	* mangle.c (write_template_prefix): Check for IDENTIFIER_NODE.
	Refactor to only check once.
	(write_unqualified_id): Use REAL_IDENTIFIER_TYPE_VALUE.
	(hash_type): Likewise.
	(compare_type): Likewise.
	(mangle_conv_op_name_for_type): Likewise.
	* name-lookup.c (do_class_using_decl): Likewise.
	(find_parameter_packs_r): Likewise.
	(lookup_template_function): Check for IDENTIFIER_NODE.
	(any_template_arguments_need_structural_equality_p): Likewise.
	(tsubst_identifier): New function.
	(tsubst_copy, tsubst_copy_and_build): Call it.
	* repo.c (repo_emit_p): Use REAL_IDENTIFIER_TYPE_VALUE.
	* rtti.c (get_tinfo_decl, tinfo_base_init): Likewise.
	(emit_tinfo_decl): Likewise.
	* search.c (lookup_fnfields_1): Likewise.
	(lookup_member): Check for IDENTIFIER_NODE.
	* semantics.c (finish_id_expression): Use REAL_IDENTIFIER_TYPE_VALUE.
	(finish_id_expression): Check for IDENTIFIER_NODE.
	* typeck.c (finish_class_member_access_expr): Likewise.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fd28593..a3e59b0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -222,6 +222,7 @@ struct GTY(()) lang_identifier {
   cxx_binding *bindings;
   tree class_template_info;
   tree label_value;
+  tree local_class_scope_type;
 };
 
 /* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
@@ -448,13 +449,15 @@ typedef enum impl_conv_void {
 #define IDENTIFIER_BINDING(NODE) \
   (LANG_IDENTIFIER_CAST (NODE)->bindings)
 
-/* TREE_TYPE only indicates on local and class scope the current
-   type. For namespace scope, the presence of a type in any namespace
-   is indicated with global_type_node, and the real type behind must
-   be found through lookup.  */
+/* For namespace scope, the presence of a type in any namespace is
+   indicated with global_type_node, and the real type behind must be
+   found through lookup.  For local and class scope, we can grab the
+   type from the identifier directly.  */
 #define IDENTIFIER_TYPE_VALUE(NODE) identifier_type_value (NODE)
-#define REAL_IDENTIFIER_TYPE_VALUE(NODE) TREE_TYPE (NODE)
-#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = (TYPE))
+#define REAL_IDENTIFIER_TYPE_VALUE(NODE) \
+  (LANG_IDENTIFIER_CAST (NODE)->local_class_scope_type)
+#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) \
+  (REAL_IDENTIFIER_TYPE_VALUE (NODE) = (TYPE))
 #define IDENTIFIER_HAS_TYPE_VALUE(NODE) (IDENTIFIER_TYPE_VALUE (NODE) ? 1 : 0)
 
 #define IDENTIFIER_LABEL_VALUE(NODE) \
@@ -1104,7 +1107,10 @@ struct GTY(()) language_function {
 
 #define error_operand_p(NODE)					\
   ((NODE) == error_mark_node					\
-   || ((NODE) && TREE_TYPE ((NODE)) == error_mark_node))
+    || ((NODE)							\
+	&& ((TREE_CODE (NODE) == IDENTIFIER_NODE		\
+	     ? REAL_IDENTIFIER_TYPE_VALUE (NODE)		\
+	     : TREE_TYPE (NODE)) == error_mark_node)))
 \f
 /* TRUE if a tree code represents a statement.  */
 extern bool statement_code_p[MAX_TREE_CODES];
@@ -2121,8 +2127,10 @@ struct GTY((variable_size)) lang_decl {
 
 /* If FN is a conversion operator, the type to which it converts.
    Otherwise, NULL_TREE.  */
-#define DECL_CONV_FN_TYPE(FN) \
-  (DECL_CONV_FN_P (FN) ? TREE_TYPE (DECL_NAME (FN)) : NULL_TREE)
+#define DECL_CONV_FN_TYPE(FN)			 \
+  (DECL_CONV_FN_P (FN)				 \
+   ? REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (FN)) \
+   : NULL_TREE)
 
 /* Nonzero if NODE, which is a TEMPLATE_DECL, is a template
    conversion operator to a type dependent on the innermost template
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e1e6fe2..a0ef39f 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5897,7 +5897,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
       if (type != error_mark_node
 	  && MAYBE_CLASS_TYPE_P (type) && DECL_NAME (decl))
 	{
-	  if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type)
+	  if (REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl))
+	      && TREE_TYPE (decl) != type)
 	    warning (0, "shadowing previous type declaration of %q#D", decl);
 	  set_identifier_type_value (DECL_NAME (decl), decl);
 	}
@@ -7501,7 +7502,10 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
   if (error_operand_p (size))
     return error_mark_node;
 
-  type = TREE_TYPE (size);
+  type = (TREE_CODE (size) == IDENTIFIER_NODE
+	  ? REAL_IDENTIFIER_TYPE_VALUE (size)
+	  : TREE_TYPE (size)); 
+
   /* type_dependent_expression_p? */
   if (!dependent_type_p (type))
     {
@@ -8124,7 +8128,7 @@ grokdeclarator (const cp_declarator *declarator,
 		  {
 		    gcc_assert (flags == NO_SPECIAL);
 		    flags = TYPENAME_FLAG;
-		    ctor_return_type = TREE_TYPE (dname);
+		    ctor_return_type = REAL_IDENTIFIER_TYPE_VALUE (dname);
 		    sfk = sfk_conversion;
 		    if (is_typename_at_global_scope (dname))
 		      name = identifier_to_locale (IDENTIFIER_POINTER (dname));
@@ -10707,7 +10711,7 @@ grok_op_properties (tree decl, bool complain)
 	     warn again about out-of-class definitions.  */
 	  && class_type == current_class_type)
 	{
-	  tree t = TREE_TYPE (name);
+	  tree t = REAL_IDENTIFIER_TYPE_VALUE (name);
 	  int ref = (TREE_CODE (t) == REFERENCE_TYPE);
 
 	  if (ref)
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index fa114ba..ce73229 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1964,7 +1964,10 @@ constrain_visibility_for_template (tree decl, tree targs)
       tree arg = TREE_VEC_ELT (args, i-1);
       if (TYPE_P (arg))
 	vis = type_visibility (arg);
-      else if (TREE_TYPE (arg) && POINTER_TYPE_P (TREE_TYPE (arg)))
+      else if (TREE_CODE (arg) == IDENTIFIER_NODE
+	       ? (REAL_IDENTIFIER_TYPE_VALUE (arg)
+		  && POINTER_TYPE_P (REAL_IDENTIFIER_TYPE_VALUE (arg)))
+	       : (TREE_TYPE (arg) && POINTER_TYPE_P (TREE_TYPE (arg))))
 	{
 	  STRIP_NOPS (arg);
 	  if (TREE_CODE (arg) == ADDR_EXPR)
@@ -2072,7 +2075,7 @@ determine_visibility (tree decl)
 	{
 	  /* Under -fvisibility-ms-compat, types are visible by default,
 	     even though their contents aren't.  */
-	  tree underlying_type = TREE_TYPE (DECL_NAME (decl));
+	  tree underlying_type = REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl));
 	  int underlying_vis = type_visibility (underlying_type);
 	  if (underlying_vis == VISIBILITY_ANON
 	      || (CLASS_TYPE_P (underlying_type)
@@ -2083,16 +2086,17 @@ determine_visibility (tree decl)
 	}
       else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl))
 	{
+	  tree id_type = REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl));
+
 	  /* tinfo visibility is based on the type it's for.  */
-	  constrain_visibility
-	    (decl, type_visibility (TREE_TYPE (DECL_NAME (decl))));
+	  constrain_visibility (decl, type_visibility (id_type));
 
 	  /* Give the target a chance to override the visibility associated
 	     with DECL.  */
 	  if (TREE_PUBLIC (decl)
 	      && !DECL_REALLY_EXTERN (decl)
-	      && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl)))
-	      && !CLASSTYPE_VISIBILITY_SPECIFIED (TREE_TYPE (DECL_NAME (decl))))
+	      && CLASS_TYPE_P (id_type)
+	      && !CLASSTYPE_VISIBILITY_SPECIFIED (id_type))
 	    targetm.cxx.determine_class_data_visibility (decl);
 	}
       else if (use_template)
@@ -2449,7 +2453,7 @@ import_export_decl (tree decl)
     }
   else if (TREE_CODE (decl) == VAR_DECL && DECL_TINFO_P (decl))
     {
-      tree type = TREE_TYPE (DECL_NAME (decl));
+      tree type = REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl));
       if (CLASS_TYPE_P (type))
 	{
 	  class_type = type;
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 28305d2..50a846f 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1011,7 +1011,7 @@ dump_decl (tree t, int flags)
 	{
 	  pp_cxx_ws_string (cxx_pp, "operator");
 	  /* Not exactly IDENTIFIER_TYPE_VALUE.  */
-	  dump_type (TREE_TYPE (t), flags);
+	  dump_type (REAL_IDENTIFIER_TYPE_VALUE (t), flags);
 	  break;
 	}
       else
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index e4d53c5..236248e 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1094,16 +1094,20 @@ write_template_prefix (const tree node)
   if (find_substitution (substitution))
     return;
 
+  type = (TREE_CODE (templ) == IDENTIFIER_NODE
+	  ? REAL_IDENTIFIER_TYPE_VALUE (templ)
+	  : TREE_TYPE (templ));
+
   /* In G++ 3.2, the name of the template template parameter was used.  */
-  if (TREE_TYPE (templ)
-      && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
+  if (type
+      && TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
       && !abi_version_at_least (2))
     G.need_abi_warning = true;
 
-  if (TREE_TYPE (templ)
-      && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
+  if (type
+      && TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
       && abi_version_at_least (2))
-    write_template_param (TREE_TYPE (templ));
+    write_template_param (type);
   else
     {
       write_prefix (context);
@@ -1128,7 +1132,7 @@ static void
 write_unqualified_id (tree identifier)
 {
   if (IDENTIFIER_TYPENAME_P (identifier))
-    write_conversion_operator_name (TREE_TYPE (identifier));
+    write_conversion_operator_name (REAL_IDENTIFIER_TYPE_VALUE (identifier));
   else if (IDENTIFIER_OPNAME_P (identifier))
     {
       int i;
@@ -3321,7 +3325,8 @@ static GTY ((param_is (union tree_node))) htab_t conv_type_names;
 static hashval_t
 hash_type (const void *val)
 {
-  return (hashval_t) TYPE_UID (TREE_TYPE ((const_tree) val));
+  tree t = CONST_CAST_TREE ((const_tree) val);
+  return (hashval_t) TYPE_UID (REAL_IDENTIFIER_TYPE_VALUE (t));
 }
 
 /* Compare VAL1 (a node in the table) with VAL2 (a TYPE).  */
@@ -3329,7 +3334,8 @@ hash_type (const void *val)
 static int
 compare_type (const void *val1, const void *val2)
 {
-  return TREE_TYPE ((const_tree) val1) == (const_tree) val2;
+  return (REAL_IDENTIFIER_TYPE_VALUE (CONST_CAST_TREE ((const_tree) val1))
+	  == CONST_CAST_TREE ((const_tree) val2));
 }
 
 /* Return an identifier for the mangled unqualified name for a
@@ -3363,7 +3369,7 @@ mangle_conv_op_name_for_type (const tree type)
 
       /* Hang TYPE off the identifier so it can be found easily later
 	 when performing conversions.  */
-      TREE_TYPE (identifier) = type;
+      REAL_IDENTIFIER_TYPE_VALUE (identifier) = type;
 
       /* Set bits on the identifier so we know later it's a conversion.  */
       IDENTIFIER_OPNAME_P (identifier) = 1;
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index b5472de..d585ddc 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3001,7 +3001,7 @@ do_class_using_decl (tree scope, tree name)
   scope_dependent_p = dependent_type_p (scope);
   name_dependent_p = (scope_dependent_p
 		      || (IDENTIFIER_TYPENAME_P (name)
-			  && dependent_type_p (TREE_TYPE (name))));
+			  && dependent_type_p (REAL_IDENTIFIER_TYPE_VALUE (name))));
 
   bases_dependent_p = false;
   if (processing_template_decl)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8d28219..63445b2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3040,8 +3040,8 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
       return NULL_TREE;
 
     case IDENTIFIER_NODE:
-      cp_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd, 
-		    ppd->visited);
+      cp_walk_tree (&REAL_IDENTIFIER_TYPE_VALUE (t), &find_parameter_packs_r,
+		    ppd, ppd->visited);
       *walk_subtrees = 0;
       return NULL_TREE;
 
@@ -6600,7 +6600,9 @@ lookup_template_function (tree fns, tree arglist)
       return fns;
     }
 
-  type = TREE_TYPE (fns);
+  type = (TREE_CODE (fns) == IDENTIFIER_NODE
+	  ? REAL_IDENTIFIER_TYPE_VALUE (fns)
+	  : TREE_TYPE (fns));
   if (TREE_CODE (fns) == OVERLOAD || !type)
     type = unknown_type_node;
 
@@ -11246,6 +11248,21 @@ tsubst_qualified_id (tree qualified_id, tree args,
   return expr;
 }
 
+/* tsubst for IDENTIFIER_NODEs.  */
+
+static tree
+tsubst_identifier (tree t, tree args, tsubst_flags_t complain, tree in_decl)
+{
+  if (IDENTIFIER_TYPENAME_P (t))
+    {
+      tree new_type = tsubst (REAL_IDENTIFIER_TYPE_VALUE (t),
+			      args, complain, in_decl);
+      return mangle_conv_op_name_for_type (new_type);
+    }
+  else
+    return t;
+}
+
 /* Like tsubst, but deals with expressions.  This function just replaces
    template parms; to finish processing the resultant expression, use
    tsubst_expr.  */
@@ -11660,13 +11677,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       return tsubst (t, args, complain, in_decl);
 
     case IDENTIFIER_NODE:
-      if (IDENTIFIER_TYPENAME_P (t))
-	{
-	  tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
-	  return mangle_conv_op_name_for_type (new_type);
-	}
-      else
-	return t;
+      return tsubst_identifier (t, args, complain, in_decl);
 
     case CONSTRUCTOR:
       /* This is handled by tsubst_copy_and_build.  */
@@ -12477,11 +12488,7 @@ tsubst_copy_and_build (tree t,
 	bool non_integral_constant_expression_p;
 	const char *error_msg;
 
-	if (IDENTIFIER_TYPENAME_P (t))
-	  {
-	    tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
-	    t = mangle_conv_op_name_for_type (new_type);
-	  }
+	t = tsubst_identifier (t, args, complain, in_decl);
 
 	/* Look up the name.  */
 	decl = lookup_name (t);
@@ -18500,6 +18507,9 @@ any_template_arguments_need_structural_equality_p (tree args)
 		continue;
 	      else if (TYPE_P (arg) && TYPE_STRUCTURAL_EQUALITY_P (arg))
 		return true;
+	      else if (TREE_CODE (arg) == IDENTIFIER_NODE)
+		return (REAL_IDENTIFIER_TYPE_VALUE (arg)
+			&& TYPE_STRUCTURAL_EQUALITY_P (REAL_IDENTIFIER_TYPE_VALUE (arg)));
 	      else if (!TYPE_P (arg) && TREE_TYPE (arg)
 		       && TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (arg)))
 		return true;
diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c
index 16a192e..444f884 100644
--- a/gcc/cp/repo.c
+++ b/gcc/cp/repo.c
@@ -309,7 +309,7 @@ repo_emit_p (tree decl)
       if (DECL_VTABLE_OR_VTT_P (decl))
 	type = DECL_CONTEXT (decl);
       else if (DECL_TINFO_P (decl))
-	type = TREE_TYPE (DECL_NAME (decl));
+	type = REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl));
       if (!DECL_TEMPLATE_INSTANTIATION (decl)
 	  && (!TYPE_LANG_SPECIFIC (type)
 	      || !CLASSTYPE_TEMPLATE_INSTANTIATION (type)))
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 0feaf07..789a087 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -426,7 +426,7 @@ get_tinfo_decl (tree type)
       d = build_lang_decl (VAR_DECL, name, ti->type);
       SET_DECL_ASSEMBLER_NAME (d, name);
       /* Remember the type it is for.  */
-      TREE_TYPE (name) = type;
+      REAL_IDENTIFIER_TYPE_VALUE (name) = type;
       DECL_TINFO_P (d) = 1;
       DECL_ARTIFICIAL (d) = 1;
       DECL_IGNORED_P (d) = 1;
@@ -876,7 +876,7 @@ tinfo_base_init (tinfo_s *ti, tree target)
     /* Determine the name of the variable -- and remember with which
        type it is associated.  */
     name_name = mangle_typeinfo_string_for_type (target);
-    TREE_TYPE (name_name) = target;
+    REAL_IDENTIFIER_TYPE_VALUE (name_name) = target;
 
     name_decl = build_lang_decl (VAR_DECL, name_name, name_type);
     SET_DECL_ASSEMBLER_NAME (name_decl, name_name);
@@ -1538,7 +1538,7 @@ emit_support_tinfos (void)
 bool
 emit_tinfo_decl (tree decl)
 {
-  tree type = TREE_TYPE (DECL_NAME (decl));
+  tree type = REAL_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl));
   int in_library = typeinfo_in_lib_p (type);
 
   gcc_assert (DECL_TINFO_P (decl));
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 188f0a5..87d6736 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1259,7 +1259,7 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type)
   if (rval && is_overloaded_fn (rval))
     rval = build_baselink (rval_binfo, basetype_path, rval,
 			   (IDENTIFIER_TYPENAME_P (name)
-			   ? TREE_TYPE (name): NULL_TREE));
+			   ? REAL_IDENTIFIER_TYPE_VALUE (name): NULL_TREE));
   return rval;
 }
 
@@ -1397,7 +1397,7 @@ lookup_fnfields_1 (tree type, tree name)
       return fn ? CLASSTYPE_DESTRUCTOR_SLOT : -1;
     }
   if (IDENTIFIER_TYPENAME_P (name))
-    return lookup_conversion_operator (type, TREE_TYPE (name));
+    return lookup_conversion_operator (type, REAL_IDENTIFIER_TYPE_VALUE (name));
 
   /* Skip the conversion operators.  */
   for (i = CLASSTYPE_FIRST_CONVERSION_SLOT;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 6c8dfd7..142dc66 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2825,7 +2825,7 @@ finish_id_expression (tree id_expression,
 		  || (!dependent_type_p (scope)
 		      && !(TREE_CODE (id_expression) == IDENTIFIER_NODE
 			   && IDENTIFIER_TYPENAME_P (id_expression)
-			   && dependent_type_p (TREE_TYPE (id_expression))))))
+			   && dependent_type_p (REAL_IDENTIFIER_TYPE_VALUE (id_expression))))))
 	    {
 	      /* If the qualifying type is non-dependent (and the name
 		 does not name a conversion operator to a dependent
@@ -3029,7 +3029,9 @@ finish_id_expression (tree id_expression,
 	 type.  */
       else if (!is_overloaded_fn (decl))
 	dependent_p
-	  = dependent_type_p (TREE_TYPE (decl));
+	  = dependent_type_p (TREE_CODE (decl) == IDENTIFIER_NODE
+			      ? REAL_IDENTIFIER_TYPE_VALUE (decl)
+			      : TREE_TYPE (decl));
       /* For a set of overloaded functions, check each of the
 	 functions.  */
       else
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index c062f0f..2fe7483 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2452,7 +2452,9 @@ finish_class_member_access_expr (tree object, tree name, bool template_p,
   if (!objc_is_public (object, name))
     return error_mark_node;
 
-  object_type = TREE_TYPE (object);
+  object_type = (TREE_CODE (object) == IDENTIFIER_NODE
+		 ? REAL_IDENTIFIER_TYPE_VALUE (object)
+		 : TREE_TYPE (object));
 
   if (processing_template_decl)
     {
-- 
1.7.0.4

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

* [PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (8 preceding siblings ...)
  2011-03-11  4:24 ` [PATCH 01/18] add typed_tree structure Nathan Froyd
@ 2011-03-11  4:24 ` Nathan Froyd
  2011-05-11  0:34   ` Nathan Froyd
  2011-03-11  4:24 ` [PATCH 08/18] convert cp *FOR_STMTs to use private scope fields Nathan Froyd
                   ` (9 subsequent siblings)
  19 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

After all that, we can finally make tree_exp inherit from typed_tree.
Quite anticlimatic.

-Nathan

gcc/
	* tree.h (struct tree_exp): Inherit from struct typed_tree.
	* tree.c (initialize_tree_contains_struct): Mark TS_EXP as TS_TYPED
	instead of TS_COMMON.

diff --git a/gcc/tree.c b/gcc/tree.c
index d63e7d5..16100a6 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -378,6 +378,7 @@ initialize_tree_contains_struct (void)
 	case TS_COMPLEX:
 	case TS_SSA_NAME:
 	case TS_CONSTRUCTOR:
+	case TS_EXP:
 	  MARK_TS_TYPED (code);
 	  break;
 
@@ -386,7 +387,6 @@ initialize_tree_contains_struct (void)
 	case TS_TYPE:
 	case TS_LIST:
 	case TS_VEC:
-	case TS_EXP:
 	case TS_BLOCK:
 	case TS_BINFO:
 	case TS_STATEMENT_LIST:
diff --git a/gcc/tree.h b/gcc/tree.h
index c81186a..461674c 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1905,7 +1905,7 @@ enum omp_clause_default_kind
   (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEFAULT)->omp_clause.subcode.default_kind)
 
 struct GTY(()) tree_exp {
-  struct tree_common common;
+  struct typed_tree typed;
   location_t locus;
   tree block;
   tree GTY ((special ("tree_exp"),

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

* [PATCH 03/18] remove TREE_CHAIN from *_CST 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:24 ` [PATCH 14/18] move TS_STATEMENT_LIST to be a substructure of TS_TYPED Nathan Froyd
@ 2011-03-11  4:24 ` Nathan Froyd
  2011-03-11 13:05   ` Richard Guenther
  2011-03-11  4:24 ` [PATCH 07/18] generalize build_case_label to the rest of the compiler Nathan Froyd
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

*_CST nodes don't need TREE_CHAIN.  Make them include typed_tree instead,
mark them as such in initialize_tree_contains_struct, and don't print out
their TREE_CHAIN.

-Nathan

gcc/
	* tree.h (struct tree_int_cst, struct real_value): Include typed_tree
	instead of tree_common.
	(struct tree_fixed_cst, struct tree_string, struct tree_complex):
	Likewise.
	* tree.c (initialize_tree_contains_struct): Mark such nodes as being
	TS_TYPED rather than TS_COMMON.
	* print-tree.c (print_node): Don't print TREE_CHAIN for constants.

diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index b0c6899..3b5edeb 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -853,11 +853,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
 	      }
 	    fputc ('\"', file);
 	  }
-	  /* Print the chain at second level.  */
-	  if (indent == 4)
-	    print_node (file, "chain", TREE_CHAIN (node), indent + 4);
-	  else
-	    print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
 	  break;
 
 	case IDENTIFIER_NODE:
diff --git a/gcc/tree.c b/gcc/tree.c
index 68f40c9..7d73c74 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -370,15 +370,15 @@ initialize_tree_contains_struct (void)
 	  break;
 
 	case TS_COMMON:
-	  MARK_TS_TYPED (code);
-	  break;
-
 	case TS_INT_CST:
 	case TS_REAL_CST:
 	case TS_FIXED_CST:
 	case TS_VECTOR:
 	case TS_STRING:
 	case TS_COMPLEX:
+	  MARK_TS_TYPED (code);
+	  break;
+
 	case TS_IDENTIFIER:
 	case TS_DECL_MINIMAL:
 	case TS_TYPE:
diff --git a/gcc/tree.h b/gcc/tree.h
index 4ad2d3e..11c2f83 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1456,7 +1456,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
        && TREE_INT_CST_LOW (A) < TREE_INT_CST_LOW (B)))
 
 struct GTY(()) tree_int_cst {
-  struct tree_common common;
+  struct typed_tree typed;
   double_int int_cst;
 };
 
@@ -1469,7 +1469,7 @@ struct real_value;
 #define TREE_REAL_CST(NODE) (*TREE_REAL_CST_PTR (NODE))
 
 struct GTY(()) tree_real_cst {
-  struct tree_common common;
+  struct typed_tree typed;
   struct real_value * real_cst_ptr;
 };
 
@@ -1481,7 +1481,7 @@ struct fixed_value;
 #define TREE_FIXED_CST(NODE) (*TREE_FIXED_CST_PTR (NODE))
 
 struct GTY(()) tree_fixed_cst {
-  struct tree_common common;
+  struct typed_tree typed;
   struct fixed_value * fixed_cst_ptr;
 };
 
@@ -1491,7 +1491,7 @@ struct GTY(()) tree_fixed_cst {
   ((const char *)(STRING_CST_CHECK (NODE)->string.str))
 
 struct GTY(()) tree_string {
-  struct tree_common common;
+  struct typed_tree typed;
   int length;
   char str[1];
 };
@@ -1501,7 +1501,7 @@ struct GTY(()) tree_string {
 #define TREE_IMAGPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.imag)
 
 struct GTY(()) tree_complex {
-  struct tree_common common;
+  struct typed_tree typed;
   tree real;
   tree imag;
 };
@@ -1510,7 +1510,7 @@ struct GTY(()) tree_complex {
 #define TREE_VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elements)
 
 struct GTY(()) tree_vector {
-  struct tree_common common;
+  struct typed_tree typed;
   tree elements;
 };
 \f
-- 
1.7.0.4

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

* [PATCH 11/18] mark EXPR_PACK_EXPANSION as typed only
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (11 preceding siblings ...)
  2011-03-11  4:24 ` [PATCH 06/18] define CASE_CHAIN accessor for CASE_LABEL_EXPR Nathan Froyd
@ 2011-03-11  4:30 ` Nathan Froyd
  2011-03-11  4:30 ` [PATCH 09/18] convert cp IF_STMTs to use private scope fields Nathan Froyd
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:30 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

EXPR_PACK_EXPANSION nodes store things in TREE_CHAIN, for symmetry with
TYPE_PACK_EXPANSIONs.  In the interest of expendiency towards slimming
tree_exp, this patch moves EXPR_PACK_EXPANSION's use of TREE_CHAIN into
a local TREE_OPERAND.  I suppose the conditional would be needed in any
event later on...

The odd case in mangle.c is needed to avoid mangling
PACK_EXPANSION_PARAMETER_PACKS; doing so would lead to an ICE.

-Nathan

gcc/cp/
	* cp-tree.def (EXPR_PACK_EXPANSION): Add an operand.
	* cp-objcp-common.c (cp_common_init_ts): Mark it as TS_TYPED.
	* cp-tree.h (PACK_EXPANSION_PARAMETER_PACKS): Use the new operand
	of EXPR_PACK_EXPANSION.
	* mangle.c (write_expression): Don't mangle all of EXPR_PACK_EXPANSION.

diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 57358b1..90a4a9b 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -238,11 +238,11 @@ cp_common_init_ts (void)
   MARK_TS_COMMON (TYPEOF_TYPE);
   MARK_TS_COMMON (BASELINK);
   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_TYPED (EXPR_PACK_EXPANSION);
   MARK_TS_TYPED (SWITCH_STMT);
   MARK_TS_TYPED (IF_STMT);
   MARK_TS_TYPED (FOR_STMT);
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 42840a8..366013a 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -413,7 +413,7 @@ DEFTREECODE (TYPE_PACK_EXPANSION, "type_pack_expansion", tcc_type, 0)
 
    EXPR_PACK_EXPANSION plays precisely the same role as TYPE_PACK_EXPANSION,
    but will be used for expressions.  */
-DEFTREECODE (EXPR_PACK_EXPANSION, "expr_pack_expansion", tcc_expression, 1)
+DEFTREECODE (EXPR_PACK_EXPANSION, "expr_pack_expansion", tcc_expression, 2)
 
 /* Selects the Ith parameter out of an argument pack. This node will
    be used when instantiating pack expansions; see
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3249ef0..7bdf9e0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2713,7 +2713,10 @@ extern void decl_shadowed_for_var_insert (tree, tree);
 
 /* The list of parameter packs used in the PACK_EXPANSION_* node. The
    TREE_VALUE of each TREE_LIST contains the parameter packs.  */
-#define PACK_EXPANSION_PARAMETER_PACKS(NODE) TREE_CHAIN (NODE)
+#define PACK_EXPANSION_PARAMETER_PACKS(NODE)		\
+  *(TREE_CODE (NODE) == EXPR_PACK_EXPANSION		\
+    ? &TREE_OPERAND (NODE, 1)				\
+    : &TREE_CHAIN (TYPE_PACK_EXPANSION_CHECK (NODE)))
 
 /* Determine if this is an argument pack.  */
 #define ARGUMENT_PACK_P(NODE)                          \
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 4d2ace6..e4d53c5 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2653,6 +2653,10 @@ write_expression (tree expr)
 	      len = 2;
 	      break;
 
+	    case EXPR_PACK_EXPANSION:
+	      len = 1;
+	      break;
+
 	    default:
 	      len = TREE_OPERAND_LENGTH (expr);
 	      break;

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

* [PATCH 09/18] convert cp IF_STMTs to use private scope fields
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (12 preceding siblings ...)
  2011-03-11  4:30 ` [PATCH 11/18] mark EXPR_PACK_EXPANSION as typed only Nathan Froyd
@ 2011-03-11  4:30 ` Nathan Froyd
  2011-03-11  4:31 ` [PATCH 18/18] make TS_BLOCK a substructure of TS_BASE Nathan Froyd
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:30 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

Just like the previous *FOR_STMT conversions, except with IF_STMTs.

-Nathan

gcc/cp/
	* cp-tree.def (IF_STMT): Add an extra operand.
	* cp-objcp-common.c (cp_common_init_ts): Mark it as TS_TYPED.
	* cp-tree.h (IF_SCOPE): Define.
	* semantics.c (begin_if_stmt): Pass scope to build_stmt.
	(finish_if_stmt): Use IF_SCOPE instead of TREE_CHAIN.

diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 21fa57f..d602dfe 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -236,7 +236,6 @@ cp_common_init_ts (void)
   MARK_TS_COMMON (TEMPLATE_INFO);
   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);
@@ -245,6 +244,7 @@ cp_common_init_ts (void)
   MARK_TS_COMMON (BOUND_TEMPLATE_TEMPLATE_PARM);
   MARK_TS_COMMON (UNBOUND_CLASS_TEMPLATE);
 
+  MARK_TS_TYPED (IF_STMT);
   MARK_TS_TYPED (FOR_STMT);
   MARK_TS_TYPED (RANGE_FOR_STMT);
   MARK_TS_TYPED (AGGR_INIT_EXPR);
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index fdfe9b5..59f89b8 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -284,10 +284,10 @@ DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", tcc_expression, 1)
 DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", tcc_statement, 3)
 
 /* Represents an 'if' statement. The operands are IF_COND,
-   THEN_CLAUSE, and ELSE_CLAUSE, respectively.  */
+   THEN_CLAUSE, and ELSE_CLAUSE, and the current scope, respectively.  */
 /* ??? It is currently still necessary to distinguish between IF_STMT
    and COND_EXPR for the benefit of templates.  */
-DEFTREECODE (IF_STMT, "if_stmt", tcc_statement, 3)
+DEFTREECODE (IF_STMT, "if_stmt", tcc_statement, 4)
 
 /* Used to represent a `for' statement. The operands are
    FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively.  */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e542388..2340812 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3781,6 +3781,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define IF_COND(NODE)		TREE_OPERAND (IF_STMT_CHECK (NODE), 0)
 #define THEN_CLAUSE(NODE)	TREE_OPERAND (IF_STMT_CHECK (NODE), 1)
 #define ELSE_CLAUSE(NODE)	TREE_OPERAND (IF_STMT_CHECK (NODE), 2)
+#define IF_SCOPE(NODE)		TREE_OPERAND (IF_STMT_CHECK (NODE), 3)
 
 /* WHILE_STMT accessors. These give access to the condition of the
    while statement and the body of the while statement, respectively.  */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index c8e5619..4071494 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -662,8 +662,8 @@ begin_if_stmt (void)
 {
   tree r, scope;
   scope = do_pushlevel (sk_block);
-  r = build_stmt (input_location, IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
-  TREE_CHAIN (r) = scope;
+  r = build_stmt (input_location, IF_STMT, NULL_TREE,
+		  NULL_TREE, NULL_TREE, scope);
   begin_cond (&IF_COND (r));
   return r;
 }
@@ -711,8 +711,8 @@ finish_else_clause (tree if_stmt)
 void
 finish_if_stmt (tree if_stmt)
 {
-  tree scope = TREE_CHAIN (if_stmt);
-  TREE_CHAIN (if_stmt) = NULL;
+  tree scope = IF_SCOPE (if_stmt);
+  IF_SCOPE (if_stmt) = NULL;
   add_stmt (do_poplevel (scope));
   finish_stmt ();
 }
-- 
1.7.0.4

^ permalink raw reply	[flat|nested] 68+ 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
                   ` (14 preceding siblings ...)
  2011-03-11  4:31 ` [PATCH 18/18] make TS_BLOCK a substructure of TS_BASE Nathan Froyd
@ 2011-03-11  4:31 ` Nathan Froyd
  2011-03-11  8:12   ` Mike Stump
                     ` (4 more replies)
  2011-03-11  4:31 ` [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more Nathan Froyd
                   ` (3 subsequent siblings)
  19 siblings, 5 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:31 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] 68+ 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
                   ` (15 preceding siblings ...)
  2011-03-11  4:31 ` [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses Nathan Froyd
@ 2011-03-11  4:31 ` Nathan Froyd
  2011-03-11 13:15   ` Richard Guenther
                     ` (2 more replies)
  2011-03-11  4:50 ` [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN Nathan Froyd
                   ` (2 subsequent siblings)
  19 siblings, 3 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:31 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] 68+ messages in thread

* [PATCH 18/18] make TS_BLOCK a substructure of TS_BASE
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (13 preceding siblings ...)
  2011-03-11  4:30 ` [PATCH 09/18] convert cp IF_STMTs to use private scope fields Nathan Froyd
@ 2011-03-11  4:31 ` Nathan Froyd
  2011-05-26 18:30   ` Nathan Froyd
  2011-03-11  4:31 ` [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses Nathan Froyd
                   ` (4 subsequent siblings)
  19 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:31 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

Now that we've  encapsulated all uses of BLOCK_CHAINON properly, we can
make BLOCKs inherit from tree_base and redirect BLOCK_CHAINON to use a
tree_block-private field instead of tree_common's chain.  Doing so saves
the never-used TREE_TYPE field.

-Nathan

gcc/
	* tree.c (initialize_tree_contains_struct): Mark TS_BLOCK as
	TS_BASE instead of TS_COMMON.
	* tree.h (struct tree_block): Inherit from tree_base, not tree_common.
	Add chain field.
	(BLOCK_CHAIN): Use new chain field.

gcc/c-family/
	* c-common.c (warning_candidate_p): Check for BLOCKs.

gcc/java/
	* decl.c (poplevel): Don't access TREE_TYPE of BLOCKs.
	* expr.c (build_jni_stub): Likewise.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index da859ec..15dcd63 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2340,6 +2340,9 @@ warning_candidate_p (tree x)
   if (DECL_P (x) && DECL_ARTIFICIAL (x))
     return 0;
 
+  if (TREE_CODE (x) == BLOCK)
+    return 0;
+
   /* VOID_TYPE_P (TREE_TYPE (x)) is workaround for cp/tree.c
      (lvalue_p) crash on TRY/CATCH. */
   if (TREE_TYPE (x) == NULL_TREE || VOID_TYPE_P (TREE_TYPE (x)))
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 6e94dff..713b11a 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -1425,10 +1425,7 @@ poplevel (int keep, int reverse, int functionbody)
 
   block = 0;
   if (keep || functionbody)
-    {
-      block = make_node (BLOCK);
-      TREE_TYPE (block) = void_type_node;
-    }
+    block = make_node (BLOCK);
 
   if (current_binding_level->exception_range)
     expand_end_java_handler (current_binding_level->exception_range);
@@ -1456,7 +1453,7 @@ poplevel (int keep, int reverse, int functionbody)
 	    }
 	  *var = NULL;
 	    
-	  bind = build3 (BIND_EXPR, TREE_TYPE (block), BLOCK_VARS (block), 
+	  bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block), 
 			 BLOCK_EXPR_BODY (block), block);
 	  BIND_EXPR_BODY (bind) = current_binding_level->stmts;
 	  
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 3be1cff..b9293e0 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -2649,7 +2649,6 @@ build_jni_stub (tree method)
   method_args = DECL_ARGUMENTS (method);
   block = build_block (env_var, NULL_TREE, method_args, NULL_TREE);
   TREE_SIDE_EFFECTS (block) = 1;
-  TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
 
   /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame.  */
   body = build2 (MODIFY_EXPR, ptr_type_node, env_var,
diff --git a/gcc/tree.c b/gcc/tree.c
index 001e8c8..3518666 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -367,6 +367,7 @@ initialize_tree_contains_struct (void)
 	{
 	case TS_TYPED:
 	case TS_IDENTIFIER:
+	case TS_BLOCK:
 	  MARK_TS_BASE (code);
 	  break;
 
@@ -388,7 +389,6 @@ initialize_tree_contains_struct (void)
 	case TS_TYPE:
 	case TS_LIST:
 	case TS_VEC:
-	case TS_BLOCK:
 	case TS_BINFO:
 	case TS_OMP_CLAUSE:
 	case TS_OPTIMIZATION:
diff --git a/gcc/tree.h b/gcc/tree.h
index f4d18f8..4a23c8f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2039,9 +2039,7 @@ struct GTY(()) tree_omp_clause {
   VEC_index (tree, BLOCK_NONLOCALIZED_VARS (NODE), N)
 #define BLOCK_SUBBLOCKS(NODE) (BLOCK_CHECK (NODE)->block.subblocks)
 #define BLOCK_SUPERCONTEXT(NODE) (BLOCK_CHECK (NODE)->block.supercontext)
-/* Note: when changing this, make sure to find the places
-   that use chainon or nreverse.  */
-#define BLOCK_CHAIN(NODE) TREE_CHAIN (BLOCK_CHECK (NODE))
+#define BLOCK_CHAIN(NODE) (BLOCK_CHECK (NODE)->block.chain)
 #define BLOCK_ABSTRACT_ORIGIN(NODE) (BLOCK_CHECK (NODE)->block.abstract_origin)
 #define BLOCK_ABSTRACT(NODE) (BLOCK_CHECK (NODE)->block.abstract_flag)
 
@@ -2082,7 +2080,8 @@ struct GTY(()) tree_omp_clause {
 #define BLOCK_SOURCE_LOCATION(NODE) (BLOCK_CHECK (NODE)->block.locus)
 
 struct GTY(()) tree_block {
-  struct tree_common common;
+  struct tree_base base;
+  tree chain;
 
   unsigned abstract_flag : 1;
   unsigned block_num : 31;
-- 
1.7.0.4

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

* [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN
  2011-03-11  4:23 [4.7 PATCH 00/18] slim down a number of tree nodes Nathan Froyd
                   ` (16 preceding siblings ...)
  2011-03-11  4:31 ` [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more Nathan Froyd
@ 2011-03-11  4:50 ` Nathan Froyd
  2011-03-11 13:19   ` Richard Guenther
  2011-05-11 19:22   ` H.J. Lu
  2011-03-11  8:18 ` [4.7 PATCH 00/18] slim down a number of tree nodes Mike Stump
  2011-03-11 13:25 ` Richard Guenther
  19 siblings, 2 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11  4:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: Nathan Froyd

Move CASE_CHAIN into a local operand for CASE_LABEL_EXPR.  Nothing to
see here.

-Nathan

gcc/
	* tree.def (CASE_LABEL_EXPR): Add an operand.
	* tree.h (CASE_CHAIN): Use TREE_OPERAND instead of TREE_CHAIN.

diff --git a/gcc/tree.def b/gcc/tree.def
index eb94ad2..9c6606d 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -863,7 +863,7 @@ DEFTREECODE (SWITCH_EXPR, "switch_expr", tcc_statement, 3)
    CASE_HIGH, respectively. If CASE_LOW is NULL_TREE, the label is a
    'default' label. If CASE_HIGH is NULL_TREE, the label is a normal case
    label.  CASE_LABEL is the corresponding LABEL_DECL.  */
-DEFTREECODE (CASE_LABEL_EXPR, "case_label_expr", tcc_statement, 3)
+DEFTREECODE (CASE_LABEL_EXPR, "case_label_expr", tcc_statement, 4)
 
 /* Used to represent an inline assembly statement.  ASM_STRING returns a
    STRING_CST for the instruction (e.g., "mov x, y"). ASM_OUTPUTS,
diff --git a/gcc/tree.h b/gcc/tree.h
index 3e1ff2c..c81186a 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1689,7 +1689,7 @@ extern void protected_set_expr_location (tree, location_t);
 #define CASE_LOW(NODE)          	TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 0)
 #define CASE_HIGH(NODE)         	TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 1)
 #define CASE_LABEL(NODE)		TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 2)
-#define CASE_CHAIN(NODE)		TREE_CHAIN (CASE_LABEL_EXPR_CHECK (NODE))
+#define CASE_CHAIN(NODE)		TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 3)
 
 /* The operands of a TARGET_MEM_REF.  Operands 0 and 1 have to match
    corresponding MEM_REF operands.  */
-- 
1.7.0.4

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

* Re: [PATCH 14/18] move TS_STATEMENT_LIST to be a substructure of TS_TYPED
  2011-03-11  4:24 ` [PATCH 14/18] move TS_STATEMENT_LIST to be a substructure of TS_TYPED Nathan Froyd
@ 2011-03-11  6:01   ` Jason Merrill
  2011-03-11 12:23     ` Nathan Froyd
  0 siblings, 1 reply; 68+ messages in thread
From: Jason Merrill @ 2011-03-11  6:01 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On 03/10/2011 11:23 PM, Nathan Froyd wrote:
> The new checks in add_stmt are
> required to make sure that cur_stmt_list can always point at something
> when calling append_to_statement_list_force.

Why haven't we already pushed before we get to add_stmt?

Jason

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

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-11  4:31 ` [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
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 68+ 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] 68+ 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
                   ` (17 preceding siblings ...)
  2011-03-11  4:50 ` [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN Nathan Froyd
@ 2011-03-11  8:18 ` Mike Stump
  2011-03-11 16:00   ` Nathan Froyd
  2011-03-11 13:25 ` Richard Guenther
  19 siblings, 1 reply; 68+ 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] 68+ messages in thread

* Re: [PATCH 14/18] move TS_STATEMENT_LIST to be a substructure of TS_TYPED
  2011-03-11  6:01   ` Jason Merrill
@ 2011-03-11 12:23     ` Nathan Froyd
  0 siblings, 0 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11 12:23 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 01:01:37AM -0500, Jason Merrill wrote:
> On 03/10/2011 11:23 PM, Nathan Froyd wrote:
>> The new checks in add_stmt are
>> required to make sure that cur_stmt_list can always point at something
>> when calling append_to_statement_list_force.
>
> Why haven't we already pushed before we get to add_stmt?

That's a good question.  Possibly as a result of
append_to_statement_list_1 helpfully noticing that if we pass in a
pointer to NULL, it goes ahead and creates a list for us.  This works
nicely for the TREE_CHAIN-based stack, but not so nicely for the
VEC-based stack.

One wonders if the NULL checking in append_to_statement_list_1 could go
away...

-Nathan

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

* Re: [PATCH 07/18] generalize build_case_label to the rest of the compiler
  2011-03-11  4:24 ` [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; 68+ 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] 68+ messages in thread

* Re: [PATCH 03/18] remove TREE_CHAIN from *_CST nodes
  2011-03-11  4:24 ` [PATCH 03/18] remove TREE_CHAIN from *_CST nodes Nathan Froyd
@ 2011-03-11 13:05   ` Richard Guenther
  0 siblings, 0 replies; 68+ messages in thread
From: Richard Guenther @ 2011-03-11 13:05 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> *_CST nodes don't need TREE_CHAIN.  Make them include typed_tree instead,
> mark them as such in initialize_tree_contains_struct, and don't print out
> their TREE_CHAIN.

Ok for 4.7 if it bootstraps and tests for all languages.

Richard.

> -Nathan
>
> gcc/
>        * tree.h (struct tree_int_cst, struct real_value): Include typed_tree
>        instead of tree_common.
>        (struct tree_fixed_cst, struct tree_string, struct tree_complex):
>        Likewise.
>        * tree.c (initialize_tree_contains_struct): Mark such nodes as being
>        TS_TYPED rather than TS_COMMON.
>        * print-tree.c (print_node): Don't print TREE_CHAIN for constants.
>
> diff --git a/gcc/print-tree.c b/gcc/print-tree.c
> index b0c6899..3b5edeb 100644
> --- a/gcc/print-tree.c
> +++ b/gcc/print-tree.c
> @@ -853,11 +853,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
>              }
>            fputc ('\"', file);
>          }
> -         /* Print the chain at second level.  */
> -         if (indent == 4)
> -           print_node (file, "chain", TREE_CHAIN (node), indent + 4);
> -         else
> -           print_node_brief (file, "chain", TREE_CHAIN (node), indent + 4);
>          break;
>
>        case IDENTIFIER_NODE:
> diff --git a/gcc/tree.c b/gcc/tree.c
> index 68f40c9..7d73c74 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -370,15 +370,15 @@ initialize_tree_contains_struct (void)
>          break;
>
>        case TS_COMMON:
> -         MARK_TS_TYPED (code);
> -         break;
> -
>        case TS_INT_CST:
>        case TS_REAL_CST:
>        case TS_FIXED_CST:
>        case TS_VECTOR:
>        case TS_STRING:
>        case TS_COMPLEX:
> +         MARK_TS_TYPED (code);
> +         break;
> +
>        case TS_IDENTIFIER:
>        case TS_DECL_MINIMAL:
>        case TS_TYPE:
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 4ad2d3e..11c2f83 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -1456,7 +1456,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
>        && TREE_INT_CST_LOW (A) < TREE_INT_CST_LOW (B)))
>
>  struct GTY(()) tree_int_cst {
> -  struct tree_common common;
> +  struct typed_tree typed;
>   double_int int_cst;
>  };
>
> @@ -1469,7 +1469,7 @@ struct real_value;
>  #define TREE_REAL_CST(NODE) (*TREE_REAL_CST_PTR (NODE))
>
>  struct GTY(()) tree_real_cst {
> -  struct tree_common common;
> +  struct typed_tree typed;
>   struct real_value * real_cst_ptr;
>  };
>
> @@ -1481,7 +1481,7 @@ struct fixed_value;
>  #define TREE_FIXED_CST(NODE) (*TREE_FIXED_CST_PTR (NODE))
>
>  struct GTY(()) tree_fixed_cst {
> -  struct tree_common common;
> +  struct typed_tree typed;
>   struct fixed_value * fixed_cst_ptr;
>  };
>
> @@ -1491,7 +1491,7 @@ struct GTY(()) tree_fixed_cst {
>   ((const char *)(STRING_CST_CHECK (NODE)->string.str))
>
>  struct GTY(()) tree_string {
> -  struct tree_common common;
> +  struct typed_tree typed;
>   int length;
>   char str[1];
>  };
> @@ -1501,7 +1501,7 @@ struct GTY(()) tree_string {
>  #define TREE_IMAGPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.imag)
>
>  struct GTY(()) tree_complex {
> -  struct tree_common common;
> +  struct typed_tree typed;
>   tree real;
>   tree imag;
>  };
> @@ -1510,7 +1510,7 @@ struct GTY(()) tree_complex {
>  #define TREE_VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elements)
>
>  struct GTY(()) tree_vector {
> -  struct tree_common common;
> +  struct typed_tree typed;
>   tree elements;
>  };
>
> --
> 1.7.0.4
>
>

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

* Re: [PATCH 05/18] remove TREE_CHAIN from CONSTRUCTOR nodes
  2011-03-11  4:23 ` [PATCH 05/18] remove TREE_CHAIN from CONSTRUCTOR nodes Nathan Froyd
@ 2011-03-11 13:05   ` Richard Guenther
  0 siblings, 0 replies; 68+ messages in thread
From: Richard Guenther @ 2011-03-11 13:05 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> A straightforward conversion.

Ok for 4.7.

Thanks,
Richard.

> -Nathan
>
> gcc/
>        * tree.h (struct tree_constructor): Include typed_tree instead of
>        tree_common.
>        * tree.c (initialize_tree_contains_struct): Mark TS_CONSTRUCTOR as
>        TS_TYPED instead of TS_COMMON.
>
> diff --git a/gcc/tree.c b/gcc/tree.c
> index 072ff19..da16641 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -377,6 +377,7 @@ initialize_tree_contains_struct (void)
>        case TS_STRING:
>        case TS_COMPLEX:
>        case TS_SSA_NAME:
> +       case TS_CONSTRUCTOR:
>          MARK_TS_TYPED (code);
>          break;
>
> @@ -389,7 +390,6 @@ initialize_tree_contains_struct (void)
>        case TS_BLOCK:
>        case TS_BINFO:
>        case TS_STATEMENT_LIST:
> -       case TS_CONSTRUCTOR:
>        case TS_OMP_CLAUSE:
>        case TS_OPTIMIZATION:
>        case TS_TARGET_OPTION:
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 80888bc..35479f9 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -1614,7 +1614,7 @@ DEF_VEC_O(constructor_elt);
>  DEF_VEC_ALLOC_O(constructor_elt,gc);
>
>  struct GTY(()) tree_constructor {
> -  struct tree_common common;
> +  struct typed_tree typed;
>   VEC(constructor_elt,gc) *elts;
>  };
>
> --
> 1.7.0.4
>
>

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

* Re: [PATCH 01/18] add typed_tree structure
  2011-03-11  4:24 ` [PATCH 01/18] add typed_tree structure Nathan Froyd
@ 2011-03-11 13:05   ` Richard Guenther
  2011-03-11 15:21   ` Michael Matz
  1 sibling, 0 replies; 68+ messages in thread
From: Richard Guenther @ 2011-03-11 13:05 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> The first step in removing TREE_CHAIN (and even TREE_TYPE) from a select
> few nodes is to create separate substructures for trees-with-type and
> trees-with-chain.  Since trees-with-type but no chain are expected to be
> more common that vice versa, make the hierarchy reflect that.  Modify a
> few macros to reflect the new inheritance structure, and add a new tree
> structure enum for the new structure.  Make note that we support the new
> tree structure in the LTO streamer, even though we don't need to do
> anything about it yet.

Ok for 4.7 (I assume you have tested each patch separately for _all_
languages, or if not, will do so before applying).

Thanks,
Richard.

> -Nathan
>
> gcc/
>        * tree.h (struct typed_tree): New.
>        (struct tree_common): Include it instead of tree_base.
>        (TREE_TYPE): Update for new location of type field.
>        (TYPE_USER_ALIGN, TYPE_PACKED): Refer to base field directly.
>        (DECL_USER_ALIGN, DECL_PACKED): Likewise.
>        (union tree_node): Add typed field.
>        * treestruct.def (TS_TYPED): New.
>        * lto-streamer.c (check_handled_ts_structures): Handle it.
>        * tree.c (MARK_TS_TYPED): New macro.
>        (MARK_TS_COMMON): Call it instead of MARK_TS_BASE.
>
> diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
> index dba9d2d..546228c 100644
> --- a/gcc/lto-streamer.c
> +++ b/gcc/lto-streamer.c
> @@ -270,6 +270,7 @@ check_handled_ts_structures (void)
>   /* These are the TS_* structures that are either handled or
>      explicitly ignored by the streamer routines.  */
>   handled_p[TS_BASE] = true;
> +  handled_p[TS_TYPED] = true;
>   handled_p[TS_COMMON] = true;
>   handled_p[TS_INT_CST] = true;
>   handled_p[TS_REAL_CST] = true;
> diff --git a/gcc/tree.c b/gcc/tree.c
> index c947072..798bc08 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -356,9 +356,15 @@ initialize_tree_contains_struct (void)
>     tree_contains_struct[C][TS_BASE] = 1;              \
>   } while (0)
>
> -#define MARK_TS_COMMON(C)                              \
> +#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)
>
> diff --git a/gcc/tree.h b/gcc/tree.h
> index a49e335..2f772e1 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -407,12 +407,16 @@ struct GTY(()) tree_base {
>   unsigned address_space : 8;
>  };
>
> -struct GTY(()) tree_common {
> +struct GTY(()) typed_tree {
>   struct tree_base base;
> -  tree chain;
>   tree type;
>  };
>
> +struct GTY(()) tree_common {
> +  struct typed_tree typed;
> +  tree chain;
> +};
> +
>  /* The following table lists the uses of each of the above flags and
>    for which types of nodes they are defined.
>
> @@ -869,7 +873,7 @@ enum tree_node_structure_enum {
>    In VECTOR_TYPE nodes, this is the type of the elements.  */
>  #define TREE_TYPE(NODE) __extension__ \
>  (*({__typeof (NODE) const __t = (NODE);                                        \
> -    &__t->common.type; }))
> +    &__t->typed.type; }))
>
>  extern void tree_contains_struct_check_failed (const_tree,
>                                               const enum tree_node_structure_enum,
> @@ -2151,7 +2155,7 @@ extern enum machine_mode vector_type_mode (const_tree);
>
>  /* 1 if the alignment for this type was requested by "aligned" attribute,
>    0 if it is the default for this type.  */
> -#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->common.base.user_align)
> +#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->base.user_align)
>
>  /* The alignment for NODE, in bytes.  */
>  #define TYPE_ALIGN_UNIT(NODE) (TYPE_ALIGN (NODE) / BITS_PER_UNIT)
> @@ -2289,7 +2293,7 @@ extern enum machine_mode vector_type_mode (const_tree);
>
>  /* Indicated that objects of this type should be laid out in as
>    compact a way as possible.  */
> -#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->common.base.packed_flag)
> +#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->base.packed_flag)
>
>  /* Used by type_contains_placeholder_p to avoid recomputation.
>    Values are: 0 (unknown), 1 (false), 2 (true).  Never access
> @@ -2632,7 +2636,7 @@ struct GTY(()) tree_decl_minimal {
>  /* Set if the alignment of this DECL has been set by the user, for
>    example with an 'aligned' attribute.  */
>  #define DECL_USER_ALIGN(NODE) \
> -  (DECL_COMMON_CHECK (NODE)->common.base.user_align)
> +  (DECL_COMMON_CHECK (NODE)->base.user_align)
>  /* Holds the machine mode corresponding to the declaration of a variable or
>    field.  Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a
>    FIELD_DECL.  */
> @@ -2900,7 +2904,7 @@ struct GTY(()) tree_decl_with_rtl {
>  #define DECL_FCONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->field_decl.fcontext)
>
>  /* In a FIELD_DECL, indicates this field should be bit-packed.  */
> -#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->common.base.packed_flag)
> +#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->base.packed_flag)
>
>  /* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed
>    specially.  */
> @@ -3505,6 +3509,7 @@ extern tree build_target_option_node (void);
>  union GTY ((ptr_alias (union lang_tree_node),
>            desc ("tree_node_structure (&%h)"), variable_size)) tree_node {
>   struct tree_base GTY ((tag ("TS_BASE"))) base;
> +  struct typed_tree GTY ((tag ("TS_TYPED"))) typed;
>   struct tree_common GTY ((tag ("TS_COMMON"))) common;
>   struct tree_int_cst GTY ((tag ("TS_INT_CST"))) int_cst;
>   struct tree_real_cst GTY ((tag ("TS_REAL_CST"))) real_cst;
> diff --git a/gcc/treestruct.def b/gcc/treestruct.def
> index baea46a..b65bdc2 100644
> --- a/gcc/treestruct.def
> +++ b/gcc/treestruct.def
> @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
>    specifying what structures contain what other structures in the
>    tree_contains_struct array.  */
>  DEFTREESTRUCT(TS_BASE, "base")
> +DEFTREESTRUCT(TS_TYPED, "typed")
>  DEFTREESTRUCT(TS_COMMON, "common")
>  DEFTREESTRUCT(TS_INT_CST, "integer cst")
>  DEFTREESTRUCT(TS_REAL_CST, "real cst")
> --
> 1.7.0.4
>
>

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

* Re: [PATCH 04/18] remove TREE_CHAIN from SSA_NAME nodes
  2011-03-11  4:23 ` [PATCH 04/18] remove TREE_CHAIN from SSA_NAME nodes Nathan Froyd
@ 2011-03-11 13:06   ` Richard Guenther
  0 siblings, 0 replies; 68+ messages in thread
From: Richard Guenther @ 2011-03-11 13:06 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> This conversion is straightforward.  The tricky part is converting
> FREE_SSANAMES into a VEC to eliminate the only use of TREE_CHAIN on
> SSA_NAMEs.

Ok for 4.7.

Thanks,
Richard.

> -Nathan
>
> gcc/
>        * tree-flow.h (struct gimple_df): Make free_ssanames a VEC.
>        * tree-ssanames.c (fini_ssanames): VEC_free it.
>        (make_ssa_name_fn): Update for VECness of free_ssanames.
>        (release_ssa_name, release_dead_ssa_names): Likewise.
>        * tree.h (struct tree_ssa_name): Include typed_tree instead of
>        tree_common.
>        * tree.c (initialize_tree_contains_struct): Mark TS_SSA_NAME as
>        TS_TYPED instead of TS_COMMON.
>
> diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
> index 14c8827..6b48697 100644
> --- a/gcc/tree-flow.h
> +++ b/gcc/tree-flow.h
> @@ -61,7 +61,7 @@ struct GTY(()) gimple_df {
>   struct pointer_map_t * GTY((skip(""))) decls_to_pointers;
>
>   /* Free list of SSA_NAMEs.  */
> -  tree free_ssanames;
> +  VEC(tree,gc) *free_ssanames;
>
>   /* Hashtable holding definition for symbol.  If this field is not NULL, it
>      means that the first reference to this variable in the function is a
> diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
> index c76dba5..06cdbee 100644
> --- a/gcc/tree-ssanames.c
> +++ b/gcc/tree-ssanames.c
> @@ -96,7 +96,7 @@ void
>  fini_ssanames (void)
>  {
>   VEC_free (tree, gc, SSANAMES (cfun));
> -  FREE_SSANAMES (cfun) = NULL;
> +  VEC_free (tree, gc, FREE_SSANAMES (cfun));
>  }
>
>  /* Dump some simple statistics regarding the re-use of SSA_NAME nodes.  */
> @@ -124,10 +124,9 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
>   gcc_assert (DECL_P (var));
>
>   /* If our free list has an element, then use it.  */
> -  if (FREE_SSANAMES (fn))
> +  if (!VEC_empty (tree, FREE_SSANAMES (fn)))
>     {
> -      t = FREE_SSANAMES (fn);
> -      FREE_SSANAMES (fn) = TREE_CHAIN (FREE_SSANAMES (fn));
> +      t = VEC_pop (tree, FREE_SSANAMES (fn));
>  #ifdef GATHER_STATISTICS
>       ssa_name_nodes_reused++;
>  #endif
> @@ -234,9 +233,8 @@ release_ssa_name (tree var)
>       /* Note this SSA_NAME is now in the first list.  */
>       SSA_NAME_IN_FREE_LIST (var) = 1;
>
> -      /* And finally link it into the free list.  */
> -      TREE_CHAIN (var) = FREE_SSANAMES (cfun);
> -      FREE_SSANAMES (cfun) = var;
> +      /* And finally put it on the free list.  */
> +      VEC_safe_push (tree, gc, FREE_SSANAMES (cfun), var);
>     }
>  }
>
> @@ -334,8 +332,8 @@ replace_ssa_name_symbol (tree ssa_name, tree sym)
>  static unsigned int
>  release_dead_ssa_names (void)
>  {
> -  tree t, next;
> -  int n = 0;
> +  tree t;
> +  int n = VEC_length (tree, FREE_SSANAMES (cfun));
>   referenced_var_iterator rvi;
>
>   /* Current defs point to various dead SSA names that in turn point to
> @@ -343,17 +341,7 @@ release_dead_ssa_names (void)
>   FOR_EACH_REFERENCED_VAR (cfun, t, rvi)
>     set_current_def (t, NULL);
>   /* Now release the freelist.  */
> -  for (t = FREE_SSANAMES (cfun); t; t = next)
> -    {
> -      next = TREE_CHAIN (t);
> -      /* Dangling pointers might make GGC to still see dead SSA names, so it is
> -        important to unlink the list and avoid GGC from seeing all subsequent
> -        SSA names.  In longer run we want to have all dangling pointers here
> -        removed (since they usually go through dead statements that consume
> -        considerable amounts of memory).  */
> -      TREE_CHAIN (t) = NULL_TREE;
> -      n++;
> -    }
> +  VEC_free (tree, gc, FREE_SSANAMES (cfun));
>   FREE_SSANAMES (cfun) = NULL;
>
>   statistics_counter_event (cfun, "SSA names released", n);
> diff --git a/gcc/tree.c b/gcc/tree.c
> index 7d73c74..072ff19 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -376,6 +376,7 @@ initialize_tree_contains_struct (void)
>        case TS_VECTOR:
>        case TS_STRING:
>        case TS_COMPLEX:
> +       case TS_SSA_NAME:
>          MARK_TS_TYPED (code);
>          break;
>
> @@ -385,7 +386,6 @@ initialize_tree_contains_struct (void)
>        case TS_LIST:
>        case TS_VEC:
>        case TS_EXP:
> -       case TS_SSA_NAME:
>        case TS_BLOCK:
>        case TS_BINFO:
>        case TS_STATEMENT_LIST:
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 11c2f83..80888bc 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -1970,7 +1970,7 @@ typedef struct GTY(()) ssa_use_operand_d {
>  #define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses
>
>  struct GTY(()) tree_ssa_name {
> -  struct tree_common common;
> +  struct typed_tree typed;
>
>   /* _DECL wrapped by this SSA name.  */
>   tree var;
> --
> 1.7.0.4
>
>

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

* Re: [PATCH 06/18] define CASE_CHAIN accessor for CASE_LABEL_EXPR
  2011-03-11  4:24 ` [PATCH 06/18] define CASE_CHAIN accessor for CASE_LABEL_EXPR Nathan Froyd
@ 2011-03-11 13:07   ` Richard Guenther
  0 siblings, 0 replies; 68+ messages in thread
From: Richard Guenther @ 2011-03-11 13:07 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> This patch begins a subseries of patches aimed at removing TREE_CHAIN
> from expression trees.  tree-cfg.c uses TREE_CHAIN for some analysis
> steps on CASE_LABEL_EXPRs.  I looked at this for a while, thinking it'd
> be easy to use VECs instead, but AFAICS, it wasn't.  I went for the next
> best thing, hiding TREE_CHAIN usage behind CASE_CHAIN; doing this will
> enable swapping out the TREE_CHAIN for a TREE_OPERAND at a later point.

Ok for 4.7.

Thanks,
Richard.

> -Nathan
>
>        * tree.h (CASE_CHAIN): Define.
>        * tree-cfg.c (edge_to_cases_cleanup, get_cases_for_edge): Use it.
>        (gimple_redirect_edge_and_branch): Likewise.
>
> diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
> index 1f533a3..bdce4cb 100644
> --- a/gcc/tree-cfg.c
> +++ b/gcc/tree-cfg.c
> @@ -838,8 +838,8 @@ edge_to_cases_cleanup (const void *key ATTRIBUTE_UNUSED, void **value,
>
>   for (t = (tree) *value; t; t = next)
>     {
> -      next = TREE_CHAIN (t);
> -      TREE_CHAIN (t) = NULL;
> +      next = CASE_CHAIN (t);
> +      CASE_CHAIN (t) = NULL;
>     }
>
>   *value = NULL;
> @@ -922,7 +922,7 @@ get_cases_for_edge (edge e, gimple t)
>       /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
>         a new chain.  */
>       slot = pointer_map_insert (edge_to_cases, this_edge);
> -      TREE_CHAIN (elt) = (tree) *slot;
> +      CASE_CHAIN (elt) = (tree) *slot;
>       *slot = elt;
>     }
>
> @@ -4900,7 +4900,7 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
>              {
>                last = cases;
>                CASE_LABEL (cases) = label;
> -               cases = TREE_CHAIN (cases);
> +               cases = CASE_CHAIN (cases);
>              }
>
>            /* If there was already an edge in the CFG, then we need
> @@ -4909,8 +4909,8 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
>              {
>                tree cases2 = get_cases_for_edge (e2, stmt);
>
> -               TREE_CHAIN (last) = TREE_CHAIN (cases2);
> -               TREE_CHAIN (cases2) = first;
> +               CASE_CHAIN (last) = CASE_CHAIN (cases2);
> +               CASE_CHAIN (cases2) = first;
>              }
>            bitmap_set_bit (touched_switch_bbs, gimple_bb (stmt)->index);
>          }
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 35479f9..58b3b9d 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -1689,6 +1689,7 @@ extern void protected_set_expr_location (tree, location_t);
>  #define CASE_LOW(NODE)                 TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 0)
>  #define CASE_HIGH(NODE)                TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 1)
>  #define CASE_LABEL(NODE)               TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 2)
> +#define CASE_CHAIN(NODE)               TREE_CHAIN (CASE_LABEL_EXPR_CHECK (NODE))
>
>  /* The operands of a TARGET_MEM_REF.  Operands 0 and 1 have to match
>    corresponding MEM_REF operands.  */
> --
> 1.7.0.4
>
>

^ permalink raw reply	[flat|nested] 68+ 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; 68+ 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] 68+ messages in thread

* Re: [PATCH 16/18] make TS_IDENTIFIER be a substructure of TS_BASE
  2011-03-11  4:24 ` [PATCH 16/18] make TS_IDENTIFIER be a substructure of TS_BASE Nathan Froyd
@ 2011-03-11 13:12   ` Richard Guenther
  2011-03-11 17:21     ` Nathan Froyd
  0 siblings, 1 reply; 68+ messages in thread
From: Richard Guenther @ 2011-03-11 13:12 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> Now that we've done the requisite surgery on the C++ FE, we can
> eliminate TREE_CHAIN and TREE_TYPE from IDENTIFIER_NODEs.  Doing so
> turns up a couple different places that need to be tweaked.
>
> The bit I'm not quite sure about is free_lang_data_in_decl and
> find_decls_types_r.  Previously, due to C++ FE machinations, we'd free
> REAL_IDENTIFIER_TYPE_VALUE naturally, through punning of TREE_TYPE.  Now
> that we've shuffled that field into lang_identifier, that bit of
> identifiers won't get freed...and I don't know if that causes problems.
> Anybody more knowledgeable than I willing to weigh in on that?

At some point we should zero-out DECL/TYPE_LANG_SPECIFIC, I
don't remember why we don't do that.

The patch is ok for 4.7 anyway.

Thanks,
Richard.

> -Nathan
>
> gcc/
>        * print-tree.c (print_node): Check for TS_TYPED structures before
>        accessing TREE_TYPE.
>        * tree.h (struct tree_identifier): Inherit from tree_base, not
>        tree_common.
>        (HT_IDENT_TO_GCC_IDENT): Adjust for said change.
>        * tree.c (initialize_tree_contains_struct): Mark TS_IDENTIFIER as
>        TS_BASE instead of TS_COMMON.
>        (free_lang_data_in_decl): Don't set TREE_TYPE of DECL_NAME.
>        (find_decls_types_r): Check for TS_TYPED structures before accessing
>        TREE_TYPE.
>        * varasm.c (assemble_name): Remove assert.
>
> gcc/c-family/
>        * c-common.h (struct c_common_identifier): Inherit from tree_base,
>        not tree_common.
>
> diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
> index e7fe209..961dea7 100644
> --- a/gcc/c-family/c-common.h
> +++ b/gcc/c-family/c-common.h
> @@ -306,7 +306,7 @@ enum c_tree_index
>  /* Identifier part common to the C front ends.  Inherits from
>    tree_identifier, despite appearances.  */
>  struct GTY(()) c_common_identifier {
> -  struct tree_common common;
> +  struct tree_base base;
>   struct cpp_hashnode node;
>  };
>
> diff --git a/gcc/print-tree.c b/gcc/print-tree.c
> index d8acd1b..1a1e33f 100644
> --- a/gcc/print-tree.c
> +++ b/gcc/print-tree.c
> @@ -321,7 +321,7 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
>       if (indent <= 4)
>        print_node_brief (file, "type", TREE_TYPE (node), indent + 4);
>     }
> -  else
> +  else if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
>     {
>       print_node (file, "type", TREE_TYPE (node), indent + 4);
>       if (TREE_TYPE (node))
> diff --git a/gcc/tree.c b/gcc/tree.c
> index 81ee05e..001e8c8 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -366,6 +366,7 @@ initialize_tree_contains_struct (void)
>       switch (ts_code)
>        {
>        case TS_TYPED:
> +       case TS_IDENTIFIER:
>          MARK_TS_BASE (code);
>          break;
>
> @@ -383,7 +384,6 @@ initialize_tree_contains_struct (void)
>          MARK_TS_TYPED (code);
>          break;
>
> -       case TS_IDENTIFIER:
>        case TS_DECL_MINIMAL:
>        case TS_TYPE:
>        case TS_LIST:
> @@ -4495,10 +4495,6 @@ free_lang_data_in_decl (tree decl)
>   TREE_LANG_FLAG_5 (decl) = 0;
>   TREE_LANG_FLAG_6 (decl) = 0;
>
> -  /* Identifiers need not have a type.  */
> -  if (DECL_NAME (decl))
> -    TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;
> -
>   free_lang_data_in_one_sizepos (&DECL_SIZE (decl));
>   free_lang_data_in_one_sizepos (&DECL_SIZE_UNIT (decl));
>   if (TREE_CODE (decl) == FIELD_DECL)
> @@ -4795,7 +4791,8 @@ find_decls_types_r (tree *tp, int *ws, void *data)
>       fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
>     }
>
> -  fld_worklist_push (TREE_TYPE (t), fld);
> +  if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
> +    fld_worklist_push (TREE_TYPE (t), fld);
>
>   return NULL_TREE;
>  }
> diff --git a/gcc/tree.h b/gcc/tree.h
> index c81186a..f4d18f8 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -1529,11 +1529,11 @@ struct GTY(()) tree_vector {
>    pointer, and vice versa.  */
>
>  #define HT_IDENT_TO_GCC_IDENT(NODE) \
> -  ((tree) ((char *) (NODE) - sizeof (struct tree_common)))
> +  ((tree) ((char *) (NODE) - sizeof (struct tree_base)))
>  #define GCC_IDENT_TO_HT_IDENT(NODE) (&((struct tree_identifier *) (NODE))->id)
>
>  struct GTY(()) tree_identifier {
> -  struct tree_common common;
> +  struct tree_base base;
>   struct ht_identifier id;
>  };
>
> diff --git a/gcc/varasm.c b/gcc/varasm.c
> index 76675cd..4c429de 100644
> --- a/gcc/varasm.c
> +++ b/gcc/varasm.c
> @@ -2300,7 +2300,6 @@ assemble_name (FILE *file, const char *name)
>       ultimate_transparent_alias_target (&id);
>       if (id != id_orig)
>        name = IDENTIFIER_POINTER (id);
> -      gcc_assert (! TREE_CHAIN (id));
>     }
>
>   assemble_name_raw (file, name);
> --
> 1.7.0.4
>
>

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

* Re: [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more
  2011-03-11  4:31 ` [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; 68+ 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] 68+ messages in thread

* Re: [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN
  2011-03-11  4:50 ` [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN Nathan Froyd
@ 2011-03-11 13:19   ` Richard Guenther
  2011-05-10 20:08     ` Nathan Froyd
  2011-05-10 20:19     ` Diego Novillo
  2011-05-11 19:22   ` H.J. Lu
  1 sibling, 2 replies; 68+ messages in thread
From: Richard Guenther @ 2011-03-11 13:19 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> Move CASE_CHAIN into a local operand for CASE_LABEL_EXPR.  Nothing to
> see here.

I wonder if there isn't a better way to do this ... like always requiring
operand 2 of SWITCH_EXPRs.

Richard.

> -Nathan
>
> gcc/
>        * tree.def (CASE_LABEL_EXPR): Add an operand.
>        * tree.h (CASE_CHAIN): Use TREE_OPERAND instead of TREE_CHAIN.
>
> diff --git a/gcc/tree.def b/gcc/tree.def
> index eb94ad2..9c6606d 100644
> --- a/gcc/tree.def
> +++ b/gcc/tree.def
> @@ -863,7 +863,7 @@ DEFTREECODE (SWITCH_EXPR, "switch_expr", tcc_statement, 3)
>    CASE_HIGH, respectively. If CASE_LOW is NULL_TREE, the label is a
>    'default' label. If CASE_HIGH is NULL_TREE, the label is a normal case
>    label.  CASE_LABEL is the corresponding LABEL_DECL.  */
> -DEFTREECODE (CASE_LABEL_EXPR, "case_label_expr", tcc_statement, 3)
> +DEFTREECODE (CASE_LABEL_EXPR, "case_label_expr", tcc_statement, 4)
>
>  /* Used to represent an inline assembly statement.  ASM_STRING returns a
>    STRING_CST for the instruction (e.g., "mov x, y"). ASM_OUTPUTS,
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 3e1ff2c..c81186a 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -1689,7 +1689,7 @@ extern void protected_set_expr_location (tree, location_t);
>  #define CASE_LOW(NODE)                 TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 0)
>  #define CASE_HIGH(NODE)                TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 1)
>  #define CASE_LABEL(NODE)               TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 2)
> -#define CASE_CHAIN(NODE)               TREE_CHAIN (CASE_LABEL_EXPR_CHECK (NODE))
> +#define CASE_CHAIN(NODE)               TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 3)
>
>  /* The operands of a TARGET_MEM_REF.  Operands 0 and 1 have to match
>    corresponding MEM_REF operands.  */
> --
> 1.7.0.4
>
>

^ permalink raw reply	[flat|nested] 68+ 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; 68+ 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] 68+ messages in thread

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-11  4:31 ` [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
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 68+ 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] 68+ 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
                   ` (18 preceding siblings ...)
  2011-03-11  8:18 ` [4.7 PATCH 00/18] slim down a number of tree nodes Mike Stump
@ 2011-03-11 13:25 ` Richard Guenther
  2011-03-11 13:42   ` Nathan Froyd
  19 siblings, 1 reply; 68+ 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] 68+ messages in thread

* Re: [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier
  2011-03-11  4:24 ` [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier Nathan Froyd
@ 2011-03-11 13:40   ` Jason Merrill
  2011-03-11 14:04     ` Nathan Froyd
  2011-03-11 14:41     ` Joseph S. Myers
  0 siblings, 2 replies; 68+ messages in thread
From: Jason Merrill @ 2011-03-11 13:40 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On 03/10/2011 11:23 PM, Nathan Froyd wrote:
> I'm not overly fond of the conditionals (especially in error_operand_p)
> but I don't think it's reasonable to make IDENTIFIER_NODE bigger and
> penalize the other FEs just because the C++ FE is playing games with
> TREE_TYPE.

The C++ FE expects that we can check the TREE_TYPE of anything that 
appears as an expression, and uses IDENTIFIER_NODE to indicate a 
dependent name within templates.  If you want to break TREE_TYPE on 
IDENTIFIER_NODE, you need to change the representation of dependent 
names so that we can continue to use TREE_TYPE on all expressions.

Jason

^ permalink raw reply	[flat|nested] 68+ 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; 68+ 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] 68+ messages in thread

* Re: [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier
  2011-03-11 13:40   ` Jason Merrill
@ 2011-03-11 14:04     ` Nathan Froyd
  2011-03-11 14:20       ` Nathan Froyd
  2011-03-11 14:41     ` Joseph S. Myers
  1 sibling, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11 14:04 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 08:40:24AM -0500, Jason Merrill wrote:
> On 03/10/2011 11:23 PM, Nathan Froyd wrote:
>> I'm not overly fond of the conditionals (especially in error_operand_p)
>> but I don't think it's reasonable to make IDENTIFIER_NODE bigger and
>> penalize the other FEs just because the C++ FE is playing games with
>> TREE_TYPE.
>
> The C++ FE expects that we can check the TREE_TYPE of anything that  
> appears as an expression, and uses IDENTIFIER_NODE to indicate a  
> dependent name within templates.  If you want to break TREE_TYPE on  
> IDENTIFIER_NODE, you need to change the representation of dependent  
> names so that we can continue to use TREE_TYPE on all expressions.

I'm confused.  Isn't this what the switching on IDENTIFIER_NODE in a
number of places is doing?  (And any future places that g++/libstdc++
didn't catch will be an ICE.)  Or are you saying that you don't want the
switching and IDENTIFIER_NODEs should retain TREE_TYPE unless and until
somebody comes forth with a better design?

-Nathan

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

* Re: [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier
  2011-03-11 14:04     ` Nathan Froyd
@ 2011-03-11 14:20       ` Nathan Froyd
  2011-03-11 15:04         ` Jason Merrill
  0 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11 14:20 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 06:04:45AM -0800, Nathan Froyd wrote:
> On Fri, Mar 11, 2011 at 08:40:24AM -0500, Jason Merrill wrote:
> > On 03/10/2011 11:23 PM, Nathan Froyd wrote:
> > The C++ FE expects that we can check the TREE_TYPE of anything that  
> > appears as an expression, and uses IDENTIFIER_NODE to indicate a  
> > dependent name within templates.  If you want to break TREE_TYPE on  
> > IDENTIFIER_NODE, you need to change the representation of dependent  
> > names so that we can continue to use TREE_TYPE on all expressions.
> 
> I'm confused.  Isn't this what the switching on IDENTIFIER_NODE in a
> number of places is doing?  (And any future places that g++/libstdc++
> didn't catch will be an ICE.)  Or are you saying that you don't want the
> switching and IDENTIFIER_NODEs should retain TREE_TYPE unless and until
> somebody comes forth with a better design?

Or, alternatively, are you saying that blindly replacing TREE_TYPE with
REAL_IDENTIFIER_TYPE_VALUE is wrong, semantically speaking, as TREE_TYPE
and REAL_IDENTIFIER_TYPE_VALUE mean different things and should be kept
separate, even if they happen to share the same storage?  And if so,
would moving that storage into lang_identifier be OK so long as the
requisite occurrences of TREE_TYPE are audited and the appropriate name
(REAL_IDENTIFIER_TYPE_VALUE vs. ...I don't know, EXPR_LIKE_TYPE) is
used?

-Nathan

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

* Re: [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier
  2011-03-11 13:40   ` Jason Merrill
  2011-03-11 14:04     ` Nathan Froyd
@ 2011-03-11 14:41     ` Joseph S. Myers
  1 sibling, 0 replies; 68+ messages in thread
From: Joseph S. Myers @ 2011-03-11 14:41 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Nathan Froyd, gcc-patches

On Fri, 11 Mar 2011, Jason Merrill wrote:

> On 03/10/2011 11:23 PM, Nathan Froyd wrote:
> > I'm not overly fond of the conditionals (especially in error_operand_p)
> > but I don't think it's reasonable to make IDENTIFIER_NODE bigger and
> > penalize the other FEs just because the C++ FE is playing games with
> > TREE_TYPE.
> 
> The C++ FE expects that we can check the TREE_TYPE of anything that appears as
> an expression, and uses IDENTIFIER_NODE to indicate a dependent name within
> templates.  If you want to break TREE_TYPE on IDENTIFIER_NODE, you need to
> change the representation of dependent names so that we can continue to use
> TREE_TYPE on all expressions.

There's a longstanding ambition to give identifiers a static type other 
than "tree".  That would tend to suggest a representation such as 
DEPENDENT_NAME_EXPR (a tree wrapping an identifier).

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH 07/18] generalize build_case_label to the rest of the compiler
  2011-03-11  4:24 ` [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; 68+ 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] 68+ messages in thread

* Re: [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier
  2011-03-11 14:20       ` Nathan Froyd
@ 2011-03-11 15:04         ` Jason Merrill
  2011-03-11 16:23           ` Nathan Froyd
  0 siblings, 1 reply; 68+ messages in thread
From: Jason Merrill @ 2011-03-11 15:04 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On 03/11/2011 09:19 AM, Nathan Froyd wrote:
> On Fri, Mar 11, 2011 at 06:04:45AM -0800, Nathan Froyd wrote:
>> On Fri, Mar 11, 2011 at 08:40:24AM -0500, Jason Merrill wrote:
>>> On 03/10/2011 11:23 PM, Nathan Froyd wrote:
>>> The C++ FE expects that we can check the TREE_TYPE of anything that
>>> appears as an expression, and uses IDENTIFIER_NODE to indicate a
>>> dependent name within templates.  If you want to break TREE_TYPE on
>>> IDENTIFIER_NODE, you need to change the representation of dependent
>>> names so that we can continue to use TREE_TYPE on all expressions.
>>
>> I'm confused.  Isn't this what the switching on IDENTIFIER_NODE in a
>> number of places is doing?  (And any future places that g++/libstdc++
>> didn't catch will be an ICE.)  Or are you saying that you don't want the
>> switching and IDENTIFIER_NODEs should retain TREE_TYPE unless and until
>> somebody comes forth with a better design?

The latter.

> Or, alternatively, are you saying that blindly replacing TREE_TYPE with
> REAL_IDENTIFIER_TYPE_VALUE is wrong, semantically speaking, as TREE_TYPE
> and REAL_IDENTIFIER_TYPE_VALUE mean different things and should be kept
> separate, even if they happen to share the same storage?

This too.  I'm surprised that them sharing the same storage hasn't 
broken anything yet.

> And if so,
> would moving that storage into lang_identifier be OK

Moving the uses of REAL_IDENTIFIER_TYPE_VALUE into lang_identifier or 
even a separate hash table would be OK.

> so long as the
> requisite occurrences of TREE_TYPE are audited and the appropriate name
> (REAL_IDENTIFIER_TYPE_VALUE vs. ...I don't know, EXPR_LIKE_TYPE) is
> used?

No, I want to keep using TREE_TYPE.  I was thinking of something more 
like the DEPENDENT_NAME_EXPR that Joseph mentioned.

Jason

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

* Re: [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more
  2011-03-11  4:31 ` [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; 68+ 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] 68+ messages in thread

* Re: [PATCH 01/18] add typed_tree structure
  2011-03-11  4:24 ` [PATCH 01/18] add typed_tree structure Nathan Froyd
  2011-03-11 13:05   ` Richard Guenther
@ 2011-03-11 15:21   ` Michael Matz
  1 sibling, 0 replies; 68+ messages in thread
From: Michael Matz @ 2011-03-11 15:21 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

Hi,

On Thu, 10 Mar 2011, Nathan Froyd wrote:

> 	* tree.h (struct typed_tree): New.

IMO this should be called tree_typed, like the other structs in tree.h .


Ciao,
Michael.

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

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-11  4:31 ` [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-04-13  2:43   ` Nathan Froyd
  4 siblings, 0 replies; 68+ 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] 68+ 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; 68+ 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] 68+ messages in thread

* Re: [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier
  2011-03-11 15:04         ` Jason Merrill
@ 2011-03-11 16:23           ` Nathan Froyd
  2011-03-11 17:17             ` Jason Merrill
  0 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11 16:23 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 10:03:43AM -0500, Jason Merrill wrote:
> On 03/11/2011 09:19 AM, Nathan Froyd wrote:
>>> I'm confused.  Isn't this what the switching on IDENTIFIER_NODE in a
>>> number of places is doing?  (And any future places that g++/libstdc++
>>> didn't catch will be an ICE.)  Or are you saying that you don't want the
>>> switching and IDENTIFIER_NODEs should retain TREE_TYPE unless and until
>>> somebody comes forth with a better design?
>
> The latter.

OK.  Well, for the time being, I can drop this particular patch and
simply eliminate TREE_CHAIN from IDENTIFIER_NODEs.  That eliminates any
issues with free_lang_decl and the like anyway.

>> Or, alternatively, are you saying that blindly replacing TREE_TYPE with
>> REAL_IDENTIFIER_TYPE_VALUE is wrong, semantically speaking, as TREE_TYPE
>> and REAL_IDENTIFIER_TYPE_VALUE mean different things and should be kept
>> separate, even if they happen to share the same storage?
>
> This too.  I'm surprised that them sharing the same storage hasn't  
> broken anything yet.
>
>> so long as the
>> requisite occurrences of TREE_TYPE are audited and the appropriate name
>> (REAL_IDENTIFIER_TYPE_VALUE vs. ...I don't know, EXPR_LIKE_TYPE) is
>> used?
>
> No, I want to keep using TREE_TYPE.  I was thinking of something more  
> like the DEPENDENT_NAME_EXPR that Joseph mentioned.

Hm.  OK.  Just as a light sketch of how this would all work, where do
DEPENDENT_NAME_EXPRs get introduced into the AST?  During parsing, or
someplace else?  What about those cases where the FE does TREE_TYPE
(DECL_NAME (X))--are those supposed to be REAL_IDENTIFIER_TYPE_VALUE or
is that supposed to be TREE_TYPE as discussed above (and if so, that
would be an impediment to moving identifiers to a separate static type,
as DECL_NAMEs should be identifiers, not generic trees...)?  There's
also cases like:

--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1011,7 +1011,7 @@ dump_decl (tree t, int flags)
     {
	pp_cxx_ws_string (cxx_pp, "operator");
        /* Not exactly IDENTIFIER_TYPE_VALUE.  */
-       dump_type (TREE_TYPE (t), flags);
+       dump_type (REAL_IDENTIFIER_TYPE_VALUE (t), flags);
        break;
     }
    else

is that supposed to be REAL_IDENTIFIER_TYPE_VALUE, the TREE_TYPE
discussed above, or yet another use?  I assume that wherever we test for
IDENTIFIER_TYPENAME_P, we're expecting these dependent types rather than
REAL_IDENTIFIER_TYPE_VALUE?

-Nathan

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

* Re: [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier
  2011-03-11 16:23           ` Nathan Froyd
@ 2011-03-11 17:17             ` Jason Merrill
  0 siblings, 0 replies; 68+ messages in thread
From: Jason Merrill @ 2011-03-11 17:17 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On 03/11/2011 11:23 AM, Nathan Froyd wrote:
> Hm.  OK.  Just as a light sketch of how this would all work, where do
> DEPENDENT_NAME_EXPRs get introduced into the AST?  During parsing, or
> someplace else?

During parsing, yes, wherever we look up a name and currently return the 
plain identifier rather than a decl.

> What about those cases where the FE does TREE_TYPE
> (DECL_NAME (X))--are those supposed to be REAL_IDENTIFIER_TYPE_VALUE

Kind of.  It seems like there are two uses:

1) Remembering that we've seen a declaration of a type with this name.
2) Remembering which type a particular tinfo or conversion op name 
corresponds to.

It probably makes sense for #2 to use a new and different macro.

> There's also cases like:
>
> --- a/gcc/cp/error.c
> +++ b/gcc/cp/error.c
> @@ -1011,7 +1011,7 @@ dump_decl (tree t, int flags)
>       {
> 	pp_cxx_ws_string (cxx_pp, "operator");
>          /* Not exactly IDENTIFIER_TYPE_VALUE.  */
> -       dump_type (TREE_TYPE (t), flags);
> +       dump_type (REAL_IDENTIFIER_TYPE_VALUE (t), flags);
>          break;
>       }
>      else

That's #2.

Jason

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

* Re: [PATCH 16/18] make TS_IDENTIFIER be a substructure of TS_BASE
  2011-03-11 13:12   ` Richard Guenther
@ 2011-03-11 17:21     ` Nathan Froyd
  0 siblings, 0 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-03-11 17:21 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 02:12:06PM +0100, Richard Guenther wrote:
> On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> > Now that we've done the requisite surgery on the C++ FE, we can
> > eliminate TREE_CHAIN and TREE_TYPE from IDENTIFIER_NODEs.  Doing so
> > turns up a couple different places that need to be tweaked.
> 
> At some point we should zero-out DECL/TYPE_LANG_SPECIFIC, I
> don't remember why we don't do that.
> 
> The patch is ok for 4.7 anyway.

Given Jason's comments on patch 15/18, I'll be dropping chunks of this
and just eliminating TREE_CHAIN from IDENTIFIER_NODEs for now.  Since
those changes are trivial, I'm going to assume I don't need separate
approval for those (appropriate testing will of course be performed).

-Nathan

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

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-11  4:31 ` [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
  2011-03-21 13:50     ` Nathan Froyd
  2011-04-13  2:43   ` Nathan Froyd
  4 siblings, 1 reply; 68+ 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] 68+ messages in thread

* Re: [PATCH 17/18] introduce block_chainon and use BLOCK_CHAIN more
  2011-03-11  4:31 ` [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; 68+ 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] 68+ messages in thread

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-12 12:13   ` Eric Botcazou
@ 2011-03-21 13:50     ` Nathan Froyd
  2011-03-21 17:50       ` Eric Botcazou
  0 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-03-21 13:50 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

On Sat, Mar 12, 2011 at 01:08:23PM +0100, Eric Botcazou wrote:
> > 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.

Well, they never have their TREE_TYPE taken during bootstrap and test,
at least...

You're right, though; they should probably be marked as such for
completeness.  OK to commit with those additions and reordering as above
sight unseen, or would you like to see the patch?

-Nathan

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

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-21 13:50     ` Nathan Froyd
@ 2011-03-21 17:50       ` Eric Botcazou
  0 siblings, 0 replies; 68+ messages in thread
From: Eric Botcazou @ 2011-03-21 17:50 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

> You're right, though; they should probably be marked as such for
> completeness.  OK to commit with those additions and reordering as above
> sight unseen, or would you like to see the patch?

Note that I didn't ask for that, only for a comment explaining why they were 
set aside.  So it's up to you and, yes, you can commit without reposting.

-- 
Eric Botcazou

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

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-03-11  4:31 ` [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses Nathan Froyd
                     ` (3 preceding siblings ...)
  2011-03-12 12:13   ` Eric Botcazou
@ 2011-04-13  2:43   ` Nathan Froyd
  2011-04-13  2:57     ` Diego Novillo
  2011-04-13  4:02     ` Ian Lance Taylor
  4 siblings, 2 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-04-13  2:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: iant, dnovillo

On Thu, Mar 10, 2011 at 11:23:10PM -0500, Nathan Froyd 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:

http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00565.html

Ping.  I was going to commit this, but I realized I hadn't received
approval for the go or LTO bits.  They probably qualify as obvious,
given that they're exactly the same as all the other languages, but just
to rubber-stamp everything...

> gcc/go/
> 	* go-lang.c (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.

Thanks,
-Nathan

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

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-04-13  2:43   ` Nathan Froyd
@ 2011-04-13  2:57     ` Diego Novillo
  2011-04-13  4:02     ` Ian Lance Taylor
  1 sibling, 0 replies; 68+ messages in thread
From: Diego Novillo @ 2011-04-13  2:57 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, iant

On Tue, Apr 12, 2011 at 22:43, Nathan Froyd <froydnj@codesourcery.com> wrote:
> On Thu, Mar 10, 2011 at 11:23:10PM -0500, Nathan Froyd 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:
>
> http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00565.html
>
> Ping.  I was going to commit this, but I realized I hadn't received
> approval for the go or LTO bits.  They probably qualify as obvious,
> given that they're exactly the same as all the other languages, but just
> to rubber-stamp everything...
>
>> gcc/go/
>>       * go-lang.c (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.

OK.


Diego.

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

* Re: [PATCH 02/18] enforce TREE_CHAIN and TREE_TYPE accesses
  2011-04-13  2:43   ` Nathan Froyd
  2011-04-13  2:57     ` Diego Novillo
@ 2011-04-13  4:02     ` Ian Lance Taylor
  1 sibling, 0 replies; 68+ messages in thread
From: Ian Lance Taylor @ 2011-04-13  4:02 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches, dnovillo

Nathan Froyd <froydnj@codesourcery.com> writes:

> On Thu, Mar 10, 2011 at 11:23:10PM -0500, Nathan Froyd 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:
>
> http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00565.html
>
> Ping.  I was going to commit this, but I realized I hadn't received
> approval for the go or LTO bits.  They probably qualify as obvious,
> given that they're exactly the same as all the other languages, but just
> to rubber-stamp everything...
>
>> gcc/go/
>> 	* go-lang.c (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.

This is OK.

Thanks.

Ian

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

* Re: [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN
  2011-03-11 13:19   ` Richard Guenther
@ 2011-05-10 20:08     ` Nathan Froyd
  2011-05-10 20:19     ` Diego Novillo
  1 sibling, 0 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-05-10 20:08 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

On Fri, Mar 11, 2011 at 02:19:14PM +0100, Richard Guenther wrote:
> On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> > Move CASE_CHAIN into a local operand for CASE_LABEL_EXPR.  Nothing to
> > see here.
> 
> I wonder if there isn't a better way to do this ... like always requiring
> operand 2 of SWITCH_EXPRs.

I'm honestly not sure.  Would it be OK to commit the patch and discuss
other options later?  CASE_LABEL is the last expression-esque node using
TREE_CHAIN.

-Nathan

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

* Re: [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN
  2011-03-11 13:19   ` Richard Guenther
  2011-05-10 20:08     ` Nathan Froyd
@ 2011-05-10 20:19     ` Diego Novillo
  2011-05-11  9:21       ` Richard Guenther
  1 sibling, 1 reply; 68+ messages in thread
From: Diego Novillo @ 2011-05-10 20:19 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Nathan Froyd, gcc-patches

On Fri, Mar 11, 2011 at 10:19, Richard Guenther
<richard.guenther@gmail.com> wrote:
> On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
>> Move CASE_CHAIN into a local operand for CASE_LABEL_EXPR.  Nothing to
>> see here.
>
> I wonder if there isn't a better way to do this ... like always requiring
> operand 2 of SWITCH_EXPRs.

Could be, but I think it makes sense to do it in incremental steps.
This change seems like a step forward in its own sense.  I'm fine with
it.


Diego.

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

* Re: [PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED
  2011-03-11  4:24 ` [PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED Nathan Froyd
@ 2011-05-11  0:34   ` Nathan Froyd
  2011-05-17 17:51     ` [PING][PATCH " Nathan Froyd
  0 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-05-11  0:34 UTC (permalink / raw)
  To: gcc-patches

On 03/10/2011 11:23 PM, Nathan Froyd wrote:
> After all that, we can finally make tree_exp inherit from typed_tree.
> Quite anticlimatic.

Ping.  http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00559.html

-Nathan

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

* Re: [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN
  2011-05-10 20:19     ` Diego Novillo
@ 2011-05-11  9:21       ` Richard Guenther
  0 siblings, 0 replies; 68+ messages in thread
From: Richard Guenther @ 2011-05-11  9:21 UTC (permalink / raw)
  To: Diego Novillo; +Cc: Nathan Froyd, gcc-patches

On Tue, May 10, 2011 at 9:01 PM, Diego Novillo <dnovillo@google.com> wrote:
> On Fri, Mar 11, 2011 at 10:19, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>> On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <froydnj@codesourcery.com> wrote:
>>> Move CASE_CHAIN into a local operand for CASE_LABEL_EXPR.  Nothing to
>>> see here.
>>
>> I wonder if there isn't a better way to do this ... like always requiring
>> operand 2 of SWITCH_EXPRs.
>
> Could be, but I think it makes sense to do it in incremental steps.
> This change seems like a step forward in its own sense.  I'm fine with
> it.

Yeah, ok.

Richard.

>
> Diego.
>

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

* Re: [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN
  2011-03-11  4:50 ` [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN Nathan Froyd
  2011-03-11 13:19   ` Richard Guenther
@ 2011-05-11 19:22   ` H.J. Lu
  1 sibling, 0 replies; 68+ messages in thread
From: H.J. Lu @ 2011-05-11 19:22 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Thu, Mar 10, 2011 at 8:23 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> Move CASE_CHAIN into a local operand for CASE_LABEL_EXPR.  Nothing to
> see here.
>
> -Nathan
>
> gcc/
>        * tree.def (CASE_LABEL_EXPR): Add an operand.
>        * tree.h (CASE_CHAIN): Use TREE_OPERAND instead of TREE_CHAIN.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48965

This failure is kind of random.  We may have some invalid memory access.

-- 
H.J.

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

* [PING][PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED
  2011-05-11  0:34   ` Nathan Froyd
@ 2011-05-17 17:51     ` Nathan Froyd
  2011-05-23 14:58       ` Nathan Froyd
  0 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-05-17 17:51 UTC (permalink / raw)
  To: gcc-patches

On 05/10/2011 04:18 PM, Nathan Froyd wrote:
> On 03/10/2011 11:23 PM, Nathan Froyd wrote:
>> After all that, we can finally make tree_exp inherit from typed_tree.
>> Quite anticlimatic.
> 
> Ping.  http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00559.html

Ping^2.

-Nathan

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

* Re: [PING][PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED
  2011-05-17 17:51     ` [PING][PATCH " Nathan Froyd
@ 2011-05-23 14:58       ` Nathan Froyd
  2011-05-23 15:34         ` Richard Guenther
  0 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-05-23 14:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: Richard Guenther

On 05/17/2011 11:31 AM, Nathan Froyd wrote:
> On 05/10/2011 04:18 PM, Nathan Froyd wrote:
>> On 03/10/2011 11:23 PM, Nathan Froyd wrote:
>>> After all that, we can finally make tree_exp inherit from typed_tree.
>>> Quite anticlimatic.
>>
>> Ping.  http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00559.html
> 
> Ping^2.

Ping^3 to put it in Richi's INBOX. ;)

-Nathan

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

* Re: [PING][PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED
  2011-05-23 14:58       ` Nathan Froyd
@ 2011-05-23 15:34         ` Richard Guenther
  2011-05-24 18:52           ` Nathan Froyd
  0 siblings, 1 reply; 68+ messages in thread
From: Richard Guenther @ 2011-05-23 15:34 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Mon, May 23, 2011 at 4:18 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> On 05/17/2011 11:31 AM, Nathan Froyd wrote:
>> On 05/10/2011 04:18 PM, Nathan Froyd wrote:
>>> On 03/10/2011 11:23 PM, Nathan Froyd wrote:
>>>> After all that, we can finally make tree_exp inherit from typed_tree.
>>>> Quite anticlimatic.
>>>
>>> Ping.  http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00559.html
>>
>> Ping^2.
>
> Ping^3 to put it in Richi's INBOX. ;)

Ok ;)

Please check for sizeof () uses of the structs you touched sofar.
ISTR a bug about fold-checking.

Richard.

> -Nathan
>

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

* Re: [PING][PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED
  2011-05-23 15:34         ` Richard Guenther
@ 2011-05-24 18:52           ` Nathan Froyd
  2011-05-25  9:59             ` Richard Guenther
  0 siblings, 1 reply; 68+ messages in thread
From: Nathan Froyd @ 2011-05-24 18:52 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches

`0On Mon, May 23, 2011 at 04:58:06PM +0200, Richard Guenther wrote:
> On Mon, May 23, 2011 at 4:18 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> > On 05/17/2011 11:31 AM, Nathan Froyd wrote:
> >> On 05/10/2011 04:18 PM, Nathan Froyd wrote:
> >>> On 03/10/2011 11:23 PM, Nathan Froyd wrote:
> >>>> After all that, we can finally make tree_exp inherit from typed_tree.
> >>>> Quite anticlimatic.
> >>>
> >>> Ping.  http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00559.html
> >>
> >> Ping^2.
> >
> > Ping^3 to put it in Richi's INBOX. ;)
> 
> Ok ;)
>
> Please check for sizeof () uses of the structs you touched sofar.
> ISTR a bug about fold-checking.

That doesn't apply here, because I'm not renaming the struct.  But I did
find some problems with LTO when I was rebootstrapping prior to
committing; not sure how I missed these the first time through, maybe I
was mistakenly compiling without LTO support.  Since we now have things
being dumped to LTO that don't have TREE_CHAIN, we need to take care to
not access TREE_CHAIN on such things, which the patch below does.

Tested on x86_64-unknown-linux-gnu.  OK to commit?

-Nathan

gcc/
	* tree.h (struct tree_exp): Inherit from struct tree_typed.
	* tree.c (initialize_tree_contains_struct): Mark TS_EXP as TS_TYPED
	instead of TS_COMMON.

gcc/lto/
	* lto.c (lto_ft_typed): New function.
	(lto_ft_common): Call it.
	(lto_ft_constructor): Likewise.
	(lto_ft_expr): Likewise.
	(lto_fixup_prevailing_decls): Check for TS_COMMON before accessing
	TREE_CHAIN.

diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index d64ba18..1067b51 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -254,14 +254,20 @@ remember_with_vars (tree t)
 
 static void lto_fixup_types (tree);
 
-/* Fix up fields of a tree_common T.  */
+/* Fix up fields of a tree_typed T.  */
 
 static void
-lto_ft_common (tree t)
+lto_ft_typed (tree t)
 {
-  /* Fixup our type.  */
   LTO_FIXUP_TREE (TREE_TYPE (t));
+}
+
+/* Fix up fields of a tree_common T.  */
 
+static void
+lto_ft_common (tree t)
+{
+  lto_ft_typed (t);
   LTO_FIXUP_TREE (TREE_CHAIN (t));
 }
 
@@ -398,7 +404,7 @@ lto_ft_constructor (tree t)
   unsigned HOST_WIDE_INT idx;
   constructor_elt *ce;
 
-  LTO_FIXUP_TREE (TREE_TYPE (t));
+  lto_ft_typed (t);
 
   for (idx = 0;
        VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (t), idx, ce);
@@ -415,7 +421,7 @@ static void
 lto_ft_expr (tree t)
 {
   int i;
-  lto_ft_common (t);
+  lto_ft_typed (t);
   for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
     LTO_FIXUP_TREE (TREE_OPERAND (t, i));
 }
@@ -2029,7 +2035,8 @@ lto_fixup_prevailing_decls (tree t)
 {
   enum tree_code code = TREE_CODE (t);
   LTO_NO_PREVAIL (TREE_TYPE (t));
-  LTO_NO_PREVAIL (TREE_CHAIN (t));
+  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
+    LTO_NO_PREVAIL (TREE_CHAIN (t));
   if (DECL_P (t))
     {
       LTO_NO_PREVAIL (DECL_NAME (t));
diff --git a/gcc/tree.c b/gcc/tree.c
index 3357d84..9cc99fe 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -380,6 +380,7 @@ initialize_tree_contains_struct (void)
 	case TS_COMPLEX:
 	case TS_SSA_NAME:
 	case TS_CONSTRUCTOR:
+	case TS_EXP:
 	  MARK_TS_TYPED (code);
 	  break;
 
@@ -388,7 +389,6 @@ initialize_tree_contains_struct (void)
 	case TS_TYPE_COMMON:
 	case TS_LIST:
 	case TS_VEC:
-	case TS_EXP:
 	case TS_BLOCK:
 	case TS_BINFO:
 	case TS_STATEMENT_LIST:
diff --git a/gcc/tree.h b/gcc/tree.h
index 805fe06..142237f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1917,7 +1917,7 @@ enum omp_clause_default_kind
   (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEFAULT)->omp_clause.subcode.default_kind)
 
 struct GTY(()) tree_exp {
-  struct tree_common common;
+  struct tree_typed typed;
   location_t locus;
   tree block;
   tree GTY ((special ("tree_exp"),

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

* Re: [PING][PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED
  2011-05-24 18:52           ` Nathan Froyd
@ 2011-05-25  9:59             ` Richard Guenther
  0 siblings, 0 replies; 68+ messages in thread
From: Richard Guenther @ 2011-05-25  9:59 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Tue, May 24, 2011 at 7:34 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> `0On Mon, May 23, 2011 at 04:58:06PM +0200, Richard Guenther wrote:
>> On Mon, May 23, 2011 at 4:18 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
>> > On 05/17/2011 11:31 AM, Nathan Froyd wrote:
>> >> On 05/10/2011 04:18 PM, Nathan Froyd wrote:
>> >>> On 03/10/2011 11:23 PM, Nathan Froyd wrote:
>> >>>> After all that, we can finally make tree_exp inherit from typed_tree.
>> >>>> Quite anticlimatic.
>> >>>
>> >>> Ping.  http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00559.html
>> >>
>> >> Ping^2.
>> >
>> > Ping^3 to put it in Richi's INBOX. ;)
>>
>> Ok ;)
>>
>> Please check for sizeof () uses of the structs you touched sofar.
>> ISTR a bug about fold-checking.
>
> That doesn't apply here, because I'm not renaming the struct.  But I did
> find some problems with LTO when I was rebootstrapping prior to
> committing; not sure how I missed these the first time through, maybe I
> was mistakenly compiling without LTO support.  Since we now have things
> being dumped to LTO that don't have TREE_CHAIN, we need to take care to
> not access TREE_CHAIN on such things, which the patch below does.
>
> Tested on x86_64-unknown-linux-gnu.  OK to commit?

Ok.  Please see if you can adjust the lto-streamer-in/out.c machinery
to consistently handle the new TS_ classes.

Thanks,
Richard.

> -Nathan
>
> gcc/
>        * tree.h (struct tree_exp): Inherit from struct tree_typed.
>        * tree.c (initialize_tree_contains_struct): Mark TS_EXP as TS_TYPED
>        instead of TS_COMMON.
>
> gcc/lto/
>        * lto.c (lto_ft_typed): New function.
>        (lto_ft_common): Call it.
>        (lto_ft_constructor): Likewise.
>        (lto_ft_expr): Likewise.
>        (lto_fixup_prevailing_decls): Check for TS_COMMON before accessing
>        TREE_CHAIN.
>
> diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
> index d64ba18..1067b51 100644
> --- a/gcc/lto/lto.c
> +++ b/gcc/lto/lto.c
> @@ -254,14 +254,20 @@ remember_with_vars (tree t)
>
>  static void lto_fixup_types (tree);
>
> -/* Fix up fields of a tree_common T.  */
> +/* Fix up fields of a tree_typed T.  */
>
>  static void
> -lto_ft_common (tree t)
> +lto_ft_typed (tree t)
>  {
> -  /* Fixup our type.  */
>   LTO_FIXUP_TREE (TREE_TYPE (t));
> +}
> +
> +/* Fix up fields of a tree_common T.  */
>
> +static void
> +lto_ft_common (tree t)
> +{
> +  lto_ft_typed (t);
>   LTO_FIXUP_TREE (TREE_CHAIN (t));
>  }
>
> @@ -398,7 +404,7 @@ lto_ft_constructor (tree t)
>   unsigned HOST_WIDE_INT idx;
>   constructor_elt *ce;
>
> -  LTO_FIXUP_TREE (TREE_TYPE (t));
> +  lto_ft_typed (t);
>
>   for (idx = 0;
>        VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (t), idx, ce);
> @@ -415,7 +421,7 @@ static void
>  lto_ft_expr (tree t)
>  {
>   int i;
> -  lto_ft_common (t);
> +  lto_ft_typed (t);
>   for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
>     LTO_FIXUP_TREE (TREE_OPERAND (t, i));
>  }
> @@ -2029,7 +2035,8 @@ lto_fixup_prevailing_decls (tree t)
>  {
>   enum tree_code code = TREE_CODE (t);
>   LTO_NO_PREVAIL (TREE_TYPE (t));
> -  LTO_NO_PREVAIL (TREE_CHAIN (t));
> +  if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
> +    LTO_NO_PREVAIL (TREE_CHAIN (t));
>   if (DECL_P (t))
>     {
>       LTO_NO_PREVAIL (DECL_NAME (t));
> diff --git a/gcc/tree.c b/gcc/tree.c
> index 3357d84..9cc99fe 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -380,6 +380,7 @@ initialize_tree_contains_struct (void)
>        case TS_COMPLEX:
>        case TS_SSA_NAME:
>        case TS_CONSTRUCTOR:
> +       case TS_EXP:
>          MARK_TS_TYPED (code);
>          break;
>
> @@ -388,7 +389,6 @@ initialize_tree_contains_struct (void)
>        case TS_TYPE_COMMON:
>        case TS_LIST:
>        case TS_VEC:
> -       case TS_EXP:
>        case TS_BLOCK:
>        case TS_BINFO:
>        case TS_STATEMENT_LIST:
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 805fe06..142237f 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -1917,7 +1917,7 @@ enum omp_clause_default_kind
>   (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEFAULT)->omp_clause.subcode.default_kind)
>
>  struct GTY(()) tree_exp {
> -  struct tree_common common;
> +  struct tree_typed typed;
>   location_t locus;
>   tree block;
>   tree GTY ((special ("tree_exp"),
>

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

* Re: [PATCH 18/18] make TS_BLOCK a substructure of TS_BASE
  2011-03-11  4:31 ` [PATCH 18/18] make TS_BLOCK a substructure of TS_BASE Nathan Froyd
@ 2011-05-26 18:30   ` Nathan Froyd
  0 siblings, 0 replies; 68+ messages in thread
From: Nathan Froyd @ 2011-05-26 18:30 UTC (permalink / raw)
  To: gcc-patches; +Cc: richard.guenther

On Thu, Mar 10, 2011 at 11:23:26PM -0500, Nathan Froyd wrote:
> Now that we've  encapsulated all uses of BLOCK_CHAINON properly, we can
> make BLOCKs inherit from tree_base and redirect BLOCK_CHAINON to use a
> tree_block-private field instead of tree_common's chain.  Doing so saves
> the never-used TREE_TYPE field.

This patch was approved:

http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00564.html
http://gcc.gnu.org/ml/gcc-patches/2011-05/msg01844.html

However, during retesting, I hit problems in find_decls_types_r; the
following bit of code doesn't work if your trees don't have TREE_TYPE:

  if (TREE_CODE (t) != IDENTIFIER_NODE)
    fld_worklist_push (TREE_TYPE (t), fld);

This didn't show up when I was developing the patch, since the
adjustments to IDENTIFIER_NODE:

http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00561.html

had done:

@@ -4795,7 +4791,8 @@ find_decls_types_r (tree *tp, int *ws, void *data)
       fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
     }
 
-  fld_worklist_push (TREE_TYPE (t), fld);
+  if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
+    fld_worklist_push (TREE_TYPE (t), fld);
 
   return NULL_TREE;
 }

And the later BLOCK-adjusting made use of that bit.  Given that removing
TREE_TYPE from IDENTIFIER_NODE required more invasive surgery than I'm
qualified to do at this point, that bit (and several others) got
dropped, leading to our present situation.

Since Richi approved the IDENTIFIER_NODE changes, I feel justified in
committing the slightly tweaked patch below.  The relevant bit that
wasn't in the initial mail is:

@@ -4892,7 +4892,8 @@ find_decls_types_r (tree *tp, int *ws, void *data)
       fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
     }
 
-  if (TREE_CODE (t) != IDENTIFIER_NODE)
+  if (TREE_CODE (t) != IDENTIFIER_NODE
+      && CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
     fld_worklist_push (TREE_TYPE (t), fld);
 
   return NULL_TREE;

If people feel that checking TREE_CODE for BLOCK or just 'return'ing
from the BLOCK block just above would be more appropriate, I can commit
that as a followup patch.

Tested on x86_64-unknown-linux-gnu.  Committed as r174300.

-Nathan

gcc/
	* tree.c (initialize_tree_contains_struct): Mark TS_BLOCK as
	TS_BASE instead of TS_COMMON.
	* tree.h (struct tree_block): Inherit from tree_base, not tree_common.
	Add chain field.
	(BLOCK_CHAIN): Use new chain field.

gcc/c-family/
	* c-common.c (warning_candidate_p): Check for BLOCKs.

gcc/java/
	* decl.c (poplevel): Don't access TREE_TYPE of BLOCKs.
	* expr.c (build_jni_stub): Likewise.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 2d4e492..fa7ebc5 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2367,6 +2367,9 @@ warning_candidate_p (tree x)
   if (DECL_P (x) && DECL_ARTIFICIAL (x))
     return 0;
 
+  if (TREE_CODE (x) == BLOCK)
+    return 0;
+
   /* VOID_TYPE_P (TREE_TYPE (x)) is workaround for cp/tree.c
      (lvalue_p) crash on TRY/CATCH. */
   if (TREE_TYPE (x) == NULL_TREE || VOID_TYPE_P (TREE_TYPE (x)))
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 47b4ebe..e958136 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -1425,10 +1425,7 @@ poplevel (int keep, int reverse, int functionbody)
 
   block = 0;
   if (keep || functionbody)
-    {
-      block = make_node (BLOCK);
-      TREE_TYPE (block) = void_type_node;
-    }
+    block = make_node (BLOCK);
 
   if (current_binding_level->exception_range)
     expand_end_java_handler (current_binding_level->exception_range);
@@ -1456,7 +1453,7 @@ poplevel (int keep, int reverse, int functionbody)
 	    }
 	  *var = NULL;
 	    
-	  bind = build3 (BIND_EXPR, TREE_TYPE (block), BLOCK_VARS (block), 
+	  bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block), 
 			 BLOCK_EXPR_BODY (block), block);
 	  BIND_EXPR_BODY (bind) = current_binding_level->stmts;
 	  
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 3be1cff..b9293e0 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -2649,7 +2649,6 @@ build_jni_stub (tree method)
   method_args = DECL_ARGUMENTS (method);
   block = build_block (env_var, NULL_TREE, method_args, NULL_TREE);
   TREE_SIDE_EFFECTS (block) = 1;
-  TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
 
   /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame.  */
   body = build2 (MODIFY_EXPR, ptr_type_node, env_var,
diff --git a/gcc/tree.c b/gcc/tree.c
index 1dfad04..d5b5dac 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -368,6 +368,7 @@ initialize_tree_contains_struct (void)
       switch (ts_code)
 	{
 	case TS_TYPED:
+	case TS_BLOCK:
 	  MARK_TS_BASE (code);
 	  break;
 
@@ -389,7 +390,6 @@ initialize_tree_contains_struct (void)
 	case TS_TYPE_COMMON:
 	case TS_LIST:
 	case TS_VEC:
-	case TS_BLOCK:
 	case TS_BINFO:
 	case TS_STATEMENT_LIST:
 	case TS_OMP_CLAUSE:
@@ -4892,7 +4892,8 @@ find_decls_types_r (tree *tp, int *ws, void *data)
       fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld);
     }
 
-  if (TREE_CODE (t) != IDENTIFIER_NODE)
+  if (TREE_CODE (t) != IDENTIFIER_NODE
+      && CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED))
     fld_worklist_push (TREE_TYPE (t), fld);
 
   return NULL_TREE;
diff --git a/gcc/tree.h b/gcc/tree.h
index 142237f..aefaea8 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2051,9 +2051,7 @@ struct GTY(()) tree_omp_clause {
   VEC_index (tree, BLOCK_NONLOCALIZED_VARS (NODE), N)
 #define BLOCK_SUBBLOCKS(NODE) (BLOCK_CHECK (NODE)->block.subblocks)
 #define BLOCK_SUPERCONTEXT(NODE) (BLOCK_CHECK (NODE)->block.supercontext)
-/* Note: when changing this, make sure to find the places
-   that use chainon or nreverse.  */
-#define BLOCK_CHAIN(NODE) TREE_CHAIN (BLOCK_CHECK (NODE))
+#define BLOCK_CHAIN(NODE) (BLOCK_CHECK (NODE)->block.chain)
 #define BLOCK_ABSTRACT_ORIGIN(NODE) (BLOCK_CHECK (NODE)->block.abstract_origin)
 #define BLOCK_ABSTRACT(NODE) (BLOCK_CHECK (NODE)->block.abstract_flag)
 
@@ -2094,7 +2092,8 @@ struct GTY(()) tree_omp_clause {
 #define BLOCK_SOURCE_LOCATION(NODE) (BLOCK_CHECK (NODE)->block.locus)
 
 struct GTY(()) tree_block {
-  struct tree_common common;
+  struct tree_base base;
+  tree chain;
 
   unsigned abstract_flag : 1;
   unsigned block_num : 31;

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

end of thread, other threads:[~2011-05-26 17:40 UTC | newest]

Thread overview: 68+ 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:23 ` [PATCH 04/18] remove TREE_CHAIN from SSA_NAME nodes Nathan Froyd
2011-03-11 13:06   ` Richard Guenther
2011-03-11  4:23 ` [PATCH 05/18] remove TREE_CHAIN from CONSTRUCTOR nodes Nathan Froyd
2011-03-11 13:05   ` Richard Guenther
2011-03-11  4:24 ` [PATCH 14/18] move TS_STATEMENT_LIST to be a substructure of TS_TYPED Nathan Froyd
2011-03-11  6:01   ` Jason Merrill
2011-03-11 12:23     ` Nathan Froyd
2011-03-11  4:24 ` [PATCH 03/18] remove TREE_CHAIN from *_CST nodes Nathan Froyd
2011-03-11 13:05   ` Richard Guenther
2011-03-11  4:24 ` [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:24 ` [PATCH 16/18] make TS_IDENTIFIER be a substructure of TS_BASE Nathan Froyd
2011-03-11 13:12   ` Richard Guenther
2011-03-11 17:21     ` Nathan Froyd
2011-03-11  4:24 ` [PATCH 10/18] convert cp SWITCH_STMTs to use private scope fields Nathan Froyd
2011-03-11  4:24 ` [PATCH 15/18] move REAL_IDENTIFIER_TYPE_VALUE to be a field of lang_identifier Nathan Froyd
2011-03-11 13:40   ` Jason Merrill
2011-03-11 14:04     ` Nathan Froyd
2011-03-11 14:20       ` Nathan Froyd
2011-03-11 15:04         ` Jason Merrill
2011-03-11 16:23           ` Nathan Froyd
2011-03-11 17:17             ` Jason Merrill
2011-03-11 14:41     ` Joseph S. Myers
2011-03-11  4:24 ` [PATCH 01/18] add typed_tree structure Nathan Froyd
2011-03-11 13:05   ` Richard Guenther
2011-03-11 15:21   ` Michael Matz
2011-03-11  4:24 ` [PATCH 13/18] move TS_EXP to be a substructure of TS_TYPED Nathan Froyd
2011-05-11  0:34   ` Nathan Froyd
2011-05-17 17:51     ` [PING][PATCH " Nathan Froyd
2011-05-23 14:58       ` Nathan Froyd
2011-05-23 15:34         ` Richard Guenther
2011-05-24 18:52           ` Nathan Froyd
2011-05-25  9:59             ` Richard Guenther
2011-03-11  4:24 ` [PATCH 08/18] convert cp *FOR_STMTs to use private scope fields Nathan Froyd
2011-03-11  4:24 ` [PATCH 06/18] define CASE_CHAIN accessor for CASE_LABEL_EXPR Nathan Froyd
2011-03-11 13:07   ` Richard Guenther
2011-03-11  4:30 ` [PATCH 11/18] mark EXPR_PACK_EXPANSION as typed only Nathan Froyd
2011-03-11  4:30 ` [PATCH 09/18] convert cp IF_STMTs to use private scope fields Nathan Froyd
2011-03-11  4:31 ` [PATCH 18/18] make TS_BLOCK a substructure of TS_BASE Nathan Froyd
2011-05-26 18:30   ` Nathan Froyd
2011-03-11  4:31 ` [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-21 13:50     ` Nathan Froyd
2011-03-21 17:50       ` Eric Botcazou
2011-04-13  2:43   ` Nathan Froyd
2011-04-13  2:57     ` Diego Novillo
2011-04-13  4:02     ` Ian Lance Taylor
2011-03-11  4:31 ` [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:50 ` [PATCH 12/18] make CASE_LABEL_EXPR not abuse TREE_CHAIN Nathan Froyd
2011-03-11 13:19   ` Richard Guenther
2011-05-10 20:08     ` Nathan Froyd
2011-05-10 20:19     ` Diego Novillo
2011-05-11  9:21       ` Richard Guenther
2011-05-11 19:22   ` H.J. Lu
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 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).