public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][C++] Get rid of TREE_CHAIN use for TREE_VEC (NON_DEFAULT_TEMPLATE_ARGS_COUNT)
@ 2012-08-17 11:29 Richard Guenther
  2012-08-17 13:58 ` Paolo Carlini
  2012-08-20 10:50 ` Richard Guenther
  0 siblings, 2 replies; 7+ messages in thread
From: Richard Guenther @ 2012-08-17 11:29 UTC (permalink / raw)
  To: gcc-patches


This gets rid of this field, pushing it into a short int in tree_base
(hopefully 2^16 non-defaulted template args are enough ...).  The
existing code is a bit confusing because of the differences with
respect to ENABLE_CHECKING, it has very little testcase coverage as
well (a single testcase, g++.dg/template/error39.C), so I am not sure
I got the idea correct (especially as ENABLE_CHECKING vs. 
non-ENABLE_CHECKING looks to introduce subtle differences?).

Anyway, a previous iteration that failed g++.dg/template/error39.C
bootstrapped and tested all languages ok, the following version now
passes g++.dg/template/error39.C and hopefully bootstrap and regtest
as well.

We build a _lot_ of TREE_VECs from the C++ frontend, so this 8 byte
saving is quite visible.  TREE_VEC is the most used TREE_CODE by far
on PR54146:

...
ssa_name              363597
mem_ref               403966
addr_expr            1203839
tree_list            1205721
tree_vec             2654415

which translates to 109615896 bytes allocated in TREE_VECs (yes,
that includes the actual storage, the average size is 41.3 bytes,
with this patch TREE_VEC itself shrinks from 40 bytes to 32 bytes
which means the average TREE_VEC size is one!).

Let's hope removing TREE_TYPE from TREE_VEC is as "easy" ;)

Re-bootstrap and regtest running on x86_64-unknown-linux-gnu.

Ok for the C++ parts?

Thanks,
Richard.

2012-08-17  Richard Guenther  <rguenther@suse.de>

	* tree.h (struct tree_base): Put address_space into a union,
	alongside a new field non_default_template_args_count used by
	C++ TREE_VECs.
	(struct tree_vec): Derive from tree_typed instead of tree_common.
	(TYPE_ADDR_SPACE): Adjust.
	* tree.c (initialize_tree_contains_struct): Adjust tree type
	hierarchy.

	cp/
	* cp-tree.h (NON_DEFAULT_TEMPLATE_ARGS_COUNT): Remove.
	(SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT,
	GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT): Use
	non_default_template_args_count in tree_base instead of TREE_CHAIN.
	* pt.c (expand_template_argument_pack): Adjust.
	(template_parm_to_arg): Likewise.
	(current_template_args): Likewise.
	(coerce_template_parameter_pack): Likewise.
	(coerce_template_parms): Likewise.
	(tsubst_template_args): Likewise.
	(type_unification_real): Likewise.
	* parser.c (cp_parser_template_argument_list): Likewise.

Index: gcc/tree.h
===================================================================
*** gcc/tree.h	(revision 190469)
--- gcc/tree.h	(working copy)
*************** struct GTY(()) tree_base {
*** 453,465 ****
    unsigned packed_flag : 1;
    unsigned user_align : 1;
    unsigned nameless_flag : 1;
  
!   unsigned spare : 12;
! 
!   /* This field is only used with type nodes; the only reason it is present
!      in tree_base instead of tree_type is to save space.  The size of the
!      field must be large enough to hold addr_space_t values.  */
!   unsigned address_space : 8;
  };
  
  struct GTY(()) tree_typed {
--- 453,473 ----
    unsigned packed_flag : 1;
    unsigned user_align : 1;
    unsigned nameless_flag : 1;
+   unsigned spare0 : 4;
  
!   /* The following has to be at a 16-bit alignment boundary to be properly
!      packed and not make tree_base larger than 64 bits.  */
!   union tree_base_spare_bits {
!     /* This field is only used with type nodes; the only reason it is present
!        in tree_base instead of tree_type is to save space.  The size of the
!        field must be large enough to hold addr_space_t values.  */
!     unsigned char address_space;
! 
!     /* This field is only used with tree_vec nodes by the C++ frontend; the
!        only reason it is present in tree_base instead of tree_vec is to
!        save space.  */
!     unsigned short non_default_template_args_count;
!   } GTY((skip(""))) spare;
  };
  
  struct GTY(()) tree_typed {
*************** struct GTY(()) tree_list {
*** 1483,1489 ****
  #define TREE_VEC_ELT(NODE,I) TREE_VEC_ELT_CHECK (NODE, I)
  
  struct GTY(()) tree_vec {
!   struct tree_common common;
    int length;
    tree GTY ((length ("TREE_VEC_LENGTH ((tree)&%h)"))) a[1];
  };
--- 1491,1497 ----
  #define TREE_VEC_ELT(NODE,I) TREE_VEC_ELT_CHECK (NODE, I)
  
  struct GTY(()) tree_vec {
!   struct tree_typed typed;
    int length;
    tree GTY ((length ("TREE_VEC_LENGTH ((tree)&%h)"))) a[1];
  };
*************** extern enum machine_mode vector_type_mod
*** 2182,2188 ****
  #define TYPE_NAMELESS(NODE) (TYPE_CHECK (NODE)->base.nameless_flag)
  
  /* The address space the type is in.  */
! #define TYPE_ADDR_SPACE(NODE) (TYPE_CHECK (NODE)->base.address_space)
  
  /* There is a TYPE_QUAL value for each type qualifier.  They can be
     combined by bitwise-or to form the complete set of qualifiers for a
--- 2190,2196 ----
  #define TYPE_NAMELESS(NODE) (TYPE_CHECK (NODE)->base.nameless_flag)
  
  /* The address space the type is in.  */
! #define TYPE_ADDR_SPACE(NODE) (TYPE_CHECK (NODE)->base.spare.address_space)
  
  /* There is a TYPE_QUAL value for each type qualifier.  They can be
     combined by bitwise-or to form the complete set of qualifiers for a
Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 190469)
--- gcc/tree.c	(working copy)
*************** initialize_tree_contains_struct (void)
*** 382,387 ****
--- 382,388 ----
  	case TS_REAL_CST:
  	case TS_FIXED_CST:
  	case TS_VECTOR:
+ 	case TS_VEC:
  	case TS_STRING:
  	case TS_COMPLEX:
  	case TS_SSA_NAME:
*************** initialize_tree_contains_struct (void)
*** 395,401 ****
  	case TS_DECL_MINIMAL:
  	case TS_TYPE_COMMON:
  	case TS_LIST:
- 	case TS_VEC:
  	case TS_BINFO:
  	case TS_OMP_CLAUSE:
  	case TS_OPTIMIZATION:
--- 396,401 ----
Index: gcc/cp/pt.c
===================================================================
*** gcc/cp/pt.c	(revision 190469)
--- gcc/cp/pt.c	(working copy)
*************** expand_template_argument_pack (tree args
*** 3301,3307 ****
    tree result_args = NULL_TREE;
    int in_arg, out_arg = 0, nargs = args ? TREE_VEC_LENGTH (args) : 0;
    int num_result_args = -1;
!   int non_default_args_count = -1;
  
    /* First, determine if we need to expand anything, and the number of
       slots we'll need.  */
--- 3301,3307 ----
    tree result_args = NULL_TREE;
    int in_arg, out_arg = 0, nargs = args ? TREE_VEC_LENGTH (args) : 0;
    int num_result_args = -1;
!   int non_default_args_count;
  
    /* First, determine if we need to expand anything, and the number of
       slots we'll need.  */
*************** expand_template_argument_pack (tree args
*** 3331,3339 ****
  
    /* Expand arguments.  */
    result_args = make_tree_vec (num_result_args);
!   if (NON_DEFAULT_TEMPLATE_ARGS_COUNT (args))
!     non_default_args_count =
!       GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args);
    for (in_arg = 0; in_arg < nargs; ++in_arg)
      {
        tree arg = TREE_VEC_ELT (args, in_arg);
--- 3331,3337 ----
  
    /* Expand arguments.  */
    result_args = make_tree_vec (num_result_args);
!   non_default_args_count = GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args);
    for (in_arg = 0; in_arg < nargs; ++in_arg)
      {
        tree arg = TREE_VEC_ELT (args, in_arg);
*************** expand_template_argument_pack (tree args
*** 3343,3350 ****
            int i, num_packed = TREE_VEC_LENGTH (packed);
            for (i = 0; i < num_packed; ++i, ++out_arg)
              TREE_VEC_ELT (result_args, out_arg) = TREE_VEC_ELT(packed, i);
! 	  if (non_default_args_count > 0)
! 	    non_default_args_count += num_packed;
          }
        else
          {
--- 3341,3347 ----
            int i, num_packed = TREE_VEC_LENGTH (packed);
            for (i = 0; i < num_packed; ++i, ++out_arg)
              TREE_VEC_ELT (result_args, out_arg) = TREE_VEC_ELT(packed, i);
! 	  non_default_args_count += num_packed;
          }
        else
          {
*************** expand_template_argument_pack (tree args
*** 3352,3359 ****
            ++out_arg;
          }
      }
!   if (non_default_args_count >= 0)
!     SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (result_args, non_default_args_count);
    return result_args;
  }
  
--- 3349,3355 ----
            ++out_arg;
          }
      }
!   SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (result_args, non_default_args_count);
    return result_args;
  }
  
*************** template_parm_to_arg (tree t)
*** 3702,3711 ****
  	  /* Turn this argument into a TYPE_ARGUMENT_PACK
  	     with a single element, which expands T.  */
  	  tree vec = make_tree_vec (1);
! #ifdef ENABLE_CHECKING
! 	  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
! 	    (vec, TREE_VEC_LENGTH (vec));
! #endif
  	  TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
  
  	  t = cxx_make_type (TYPE_ARGUMENT_PACK);
--- 3698,3704 ----
  	  /* Turn this argument into a TYPE_ARGUMENT_PACK
  	     with a single element, which expands T.  */
  	  tree vec = make_tree_vec (1);
! 	  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
  	  TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
  
  	  t = cxx_make_type (TYPE_ARGUMENT_PACK);
*************** template_parm_to_arg (tree t)
*** 3722,3731 ****
  	     with a single element, which expands T.  */
  	  tree vec = make_tree_vec (1);
  	  tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t));
! #ifdef ENABLE_CHECKING
! 	  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
! 	    (vec, TREE_VEC_LENGTH (vec));
! #endif
  	  TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
  
  	  t  = make_node (NONTYPE_ARGUMENT_PACK);
--- 3715,3721 ----
  	     with a single element, which expands T.  */
  	  tree vec = make_tree_vec (1);
  	  tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t));
! 	  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
  	  TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
  
  	  t  = make_node (NONTYPE_ARGUMENT_PACK);
*************** current_template_args (void)
*** 3800,3808 ****
        for (i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i)
  	TREE_VEC_ELT (a, i) = template_parm_to_arg (TREE_VEC_ELT (a, i));
  
- #ifdef ENABLE_CHECKING
        SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (a, TREE_VEC_LENGTH (a));
- #endif
  
        if (length > 1)
  	TREE_VEC_ELT (args, --l) = a;
--- 3790,3796 ----
*************** coerce_template_parameter_pack (tree par
*** 6410,6419 ****
      }
  
    SET_ARGUMENT_PACK_ARGS (argument_pack, packed_args);
- #ifdef ENABLE_CHECKING
    SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (packed_args,
  				       TREE_VEC_LENGTH (packed_args));
- #endif
    return argument_pack;
  }
  
--- 6398,6405 ----
*************** coerce_template_parms (tree parms,
*** 6457,6462 ****
--- 6443,6449 ----
    tree new_inner_args;
    int saved_unevaluated_operand;
    int saved_inhibit_evaluation_warnings;
+   bool defaulted_arg_found;
  
    /* When used as a boolean value, indicates whether this is a
       variadic template parameter list. Since it's an int, we can also
*************** coerce_template_parms (tree parms,
*** 6528,6533 ****
--- 6515,6521 ----
    c_inhibit_evaluation_warnings = 0;
    new_inner_args = make_tree_vec (nparms);
    new_args = add_outermost_template_args (args, new_inner_args);
+   defaulted_arg_found = false;
    for (parm_idx = 0, arg_idx = 0; parm_idx < nparms; parm_idx++, arg_idx++)
      {
        tree arg;
*************** coerce_template_parms (tree parms,
*** 6586,6593 ****
  	  /* The position of the first default template argument,
  	     is also the number of non-defaulted arguments in NEW_INNER_ARGS.
  	     Record that.  */
! 	  if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
! 	    SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args, arg_idx);
  	}
        else
  	break;
--- 6574,6584 ----
  	  /* The position of the first default template argument,
  	     is also the number of non-defaulted arguments in NEW_INNER_ARGS.
  	     Record that.  */
! 	  if (!defaulted_arg_found)
! 	    {
! 	      defaulted_arg_found = true;
! 	      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args, arg_idx);
! 	    }
  	}
        else
  	break;
*************** coerce_template_parms (tree parms,
*** 6619,6629 ****
    if (lost)
      return error_mark_node;
  
! #ifdef ENABLE_CHECKING
!   if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,
  					 TREE_VEC_LENGTH (new_inner_args));
- #endif
  
    return new_inner_args;
  }
--- 6610,6618 ----
    if (lost)
      return error_mark_node;
  
!   if (!defaulted_arg_found)
      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,
  					 TREE_VEC_LENGTH (new_inner_args));
  
    return new_inner_args;
  }
*************** tsubst_template_args (tree t, tree args,
*** 9393,9404 ****
       It will rather be the nested TREE_VECs that will carry one.
       In other words, ORIG_T carries a non defaulted argument count only
       if it doesn't contain any nested TREE_VEC.  */
!   if (NON_DEFAULT_TEMPLATE_ARGS_COUNT (orig_t))
!     {
!       int count = GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (orig_t);
!       count += expanded_len_adjust;
!       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (t, count);
!     }
    for (i = 0, out = 0; i < len; i++)
      {
        if ((PACK_EXPANSION_P (TREE_VEC_ELT (orig_t, i))
--- 9382,9390 ----
       It will rather be the nested TREE_VECs that will carry one.
       In other words, ORIG_T carries a non defaulted argument count only
       if it doesn't contain any nested TREE_VEC.  */
!   int count = GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (orig_t);
!   count += expanded_len_adjust;
!   SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (t, count);
    for (i = 0, out = 0; i < len; i++)
      {
        if ((PACK_EXPANSION_P (TREE_VEC_ELT (orig_t, i))
*************** type_unification_real (tree tparms,
*** 14982,14995 ****
    const tree *args;
    unsigned int nargs;
    unsigned int ia;
  
    gcc_assert (TREE_CODE (tparms) == TREE_VEC);
    gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
    gcc_assert (ntparms > 0);
  
!   /* Reset the number of non-defaulted template arguments contained
!      in TARGS.  */
!   NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs) = NULL_TREE;
  
   again:
    parms = xparms;
--- 14968,14981 ----
    const tree *args;
    unsigned int nargs;
    unsigned int ia;
+   bool defaulted_arg_found;
  
    gcc_assert (TREE_CODE (tparms) == TREE_VEC);
    gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
    gcc_assert (ntparms > 0);
  
!   /* Note that we did not yet find a defaulted template argument.  */
!   defaulted_arg_found = false;
  
   again:
    parms = xparms;
*************** type_unification_real (tree tparms,
*** 15140,15147 ****
  		  /* The position of the first default template argument,
  		     is also the number of non-defaulted arguments in TARGS.
  		     Record that.  */
! 		  if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
! 		    SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
  		  continue;
  		}
  	    }
--- 15126,15136 ----
  		  /* The position of the first default template argument,
  		     is also the number of non-defaulted arguments in TARGS.
  		     Record that.  */
! 		  if (!defaulted_arg_found)
! 		    {
! 		      defaulted_arg_found = true;
! 		      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
! 		    }
  		  continue;
  		}
  	    }
*************** type_unification_real (tree tparms,
*** 15170,15179 ****
  	  return unify_parameter_deduction_failure (explain_p, tparm);
  	}
      }
! #ifdef ENABLE_CHECKING
!   if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs));
- #endif
  
    return unify_success (explain_p);
  }
--- 15159,15166 ----
  	  return unify_parameter_deduction_failure (explain_p, tparm);
  	}
      }
!   if (!defaulted_arg_found)
      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs));
  
    return unify_success (explain_p);
  }
Index: gcc/cp/cp-tree.h
===================================================================
*** gcc/cp/cp-tree.h	(revision 190469)
--- gcc/cp/cp-tree.h	(working copy)
*************** extern void decl_shadowed_for_var_insert
*** 2661,2681 ****
  #define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
  /* For a given TREE_VEC containing a template argument list,
     this property contains the number of arguments that are not
!    defaulted.  */
! #define NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) TREE_CHAIN (TREE_VEC_CHECK (NODE))
! /* Below are the setter and getter of the NON_DEFAULT_TEMPLATE_ARGS_COUNT
     property.  */
  #define SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE, INT_VALUE) \
!   NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) = build_int_cst (NULL_TREE, INT_VALUE)
! #ifdef ENABLE_CHECKING
  #define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
!     int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE))
! #else
! #define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
!   NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE) \
!   ? int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE)) \
!   : TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (NODE))
! #endif
  /* The list of typedefs - used in the template - that need
     access checking at template instantiation time.  */
  #define TI_TYPEDEFS_NEEDING_ACCESS_CHECKING(NODE) \
--- 2661,2673 ----
  #define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
  /* For a given TREE_VEC containing a template argument list,
     this property contains the number of arguments that are not
!    defaulted.  The following are the setter and getter of this
     property.  */
  #define SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE, INT_VALUE) \
!   TREE_VEC_CHECK (NODE)->base.spare.non_default_template_args_count \
!     = (INT_VALUE)
  #define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
!   ((int) TREE_VEC_CHECK (NODE)->base.spare.non_default_template_args_count)
  /* The list of typedefs - used in the template - that need
     access checking at template instantiation time.  */
  #define TI_TYPEDEFS_NEEDING_ACCESS_CHECKING(NODE) \
Index: gcc/cp/parser.c
===================================================================
*** gcc/cp/parser.c	(revision 190469)
--- gcc/cp/parser.c	(working copy)
*************** cp_parser_template_argument_list (cp_par
*** 12855,12863 ****
    parser->non_integral_constant_expression_p = saved_non_ice_p;
    parser->integral_constant_expression_p = saved_ice_p;
    parser->in_template_argument_list_p = saved_in_template_argument_list_p;
- #ifdef ENABLE_CHECKING
    SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
- #endif
    return vec;
  }
  
--- 12855,12861 ----

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

* Re: [PATCH][C++] Get rid of TREE_CHAIN use for TREE_VEC (NON_DEFAULT_TEMPLATE_ARGS_COUNT)
  2012-08-17 11:29 [PATCH][C++] Get rid of TREE_CHAIN use for TREE_VEC (NON_DEFAULT_TEMPLATE_ARGS_COUNT) Richard Guenther
@ 2012-08-17 13:58 ` Paolo Carlini
  2012-08-17 18:03   ` Mike Stump
  2012-08-20 10:50 ` Richard Guenther
  1 sibling, 1 reply; 7+ messages in thread
From: Paolo Carlini @ 2012-08-17 13:58 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches, Jason Merrill

On 08/17/2012 01:26 PM, Richard Guenther wrote:
> This gets rid of this field, pushing it into a short int in tree_base
> (hopefully 2^16 non-defaulted template args are enough ...).
Honestly, I don't think it's a trivial issue. Often and often, while 
hacking the C++ front-end I noticed the integer typee which we use while 
processing templates and I become nervous even when I see ints. In these 
64-bit days and with people using all sorts of crazy template 
metaprogramming, if I were to design these things from scratch I guess 
that I would just use longs everywhere and be done with it. At minimum, 
compare to clang? But hey, I'm new to most of the C++ front-end 
internals maybe people already discussed these topics in the past, even 
at ISO level, I don't know. I'm curious to hear Jason anyway.

Paolo.

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

* Re: [PATCH][C++] Get rid of TREE_CHAIN use for TREE_VEC (NON_DEFAULT_TEMPLATE_ARGS_COUNT)
  2012-08-17 13:58 ` Paolo Carlini
@ 2012-08-17 18:03   ` Mike Stump
  2012-08-17 19:11     ` Gabriel Dos Reis
  0 siblings, 1 reply; 7+ messages in thread
From: Mike Stump @ 2012-08-17 18:03 UTC (permalink / raw)
  To: Paolo Carlini; +Cc: Richard Guenther, gcc-patches, Jason Merrill

On Aug 17, 2012, at 6:58 AM, Paolo Carlini wrote:
> On 08/17/2012 01:26 PM, Richard Guenther wrote:
>> This gets rid of this field, pushing it into a short int in tree_base
>> (hopefully 2^16 non-defaulted template args are enough ...).
> Honestly, I don't think it's a trivial issue.

Love to hear from Jason, but, my take would be 2^16 should be enough for anyone.  I think long before people hit that limit, they would merely aggregate arguments into classes and structures.  I think in another 20-80 years, we might want to bump it back up to 32 bits, but...  I think we can safely wait until we get a compelling bug report for it.

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

* Re: [PATCH][C++] Get rid of TREE_CHAIN use for TREE_VEC (NON_DEFAULT_TEMPLATE_ARGS_COUNT)
  2012-08-17 18:03   ` Mike Stump
@ 2012-08-17 19:11     ` Gabriel Dos Reis
  2012-08-18  7:39       ` Richard Guenther
  2012-08-18  8:55       ` Paolo Carlini
  0 siblings, 2 replies; 7+ messages in thread
From: Gabriel Dos Reis @ 2012-08-17 19:11 UTC (permalink / raw)
  To: Mike Stump; +Cc: Paolo Carlini, Richard Guenther, gcc-patches, Jason Merrill

On Fri, Aug 17, 2012 at 1:03 PM, Mike Stump <mikestump@comcast.net> wrote:
> On Aug 17, 2012, at 6:58 AM, Paolo Carlini wrote:
>> On 08/17/2012 01:26 PM, Richard Guenther wrote:
>>> This gets rid of this field, pushing it into a short int in tree_base
>>> (hopefully 2^16 non-defaulted template args are enough ...).
>> Honestly, I don't think it's a trivial issue.
>
> Love to hear from Jason, but, my take would be 2^16 should be enough for anyone.  I think long before people hit that limit, they would merely aggregate arguments into classes and structures.  I think in another 20-80 years, we might want to bump it back up to 32 bits, but...  I think we can safely wait until we get a compelling bug report for it.

C++11 says that an implementation should be able to handle at least 2^10
template parameters, 2^12 members declared in a single class.  I believe
that even for automatically generated programs, 2^16 is a good limit.  I suspect
that by the time that limit is a hindrance, C++ would have gone through several
iterations and more importantly 128-bit integers would be common place, so
by that time we would have plenty of spare bits -- if we haven't already
restructured the tree data structures to use idiomatic C++ constructs that
are both more space and time efficient.

This is a very long of saying "I am comfortable with the 2^16 restriction
on the number of template parameters.  The patch needs to document
that in the usual .texi file."

-- Gaby

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

* Re: [PATCH][C++] Get rid of TREE_CHAIN use for TREE_VEC (NON_DEFAULT_TEMPLATE_ARGS_COUNT)
  2012-08-17 19:11     ` Gabriel Dos Reis
@ 2012-08-18  7:39       ` Richard Guenther
  2012-08-18  8:55       ` Paolo Carlini
  1 sibling, 0 replies; 7+ messages in thread
From: Richard Guenther @ 2012-08-18  7:39 UTC (permalink / raw)
  To: Gabriel Dos Reis
  Cc: Mike Stump, Paolo Carlini, Richard Guenther, gcc-patches, Jason Merrill

On Fri, Aug 17, 2012 at 9:11 PM, Gabriel Dos Reis
<gdr@integrable-solutions.net> wrote:
> On Fri, Aug 17, 2012 at 1:03 PM, Mike Stump <mikestump@comcast.net> wrote:
>> On Aug 17, 2012, at 6:58 AM, Paolo Carlini wrote:
>>> On 08/17/2012 01:26 PM, Richard Guenther wrote:
>>>> This gets rid of this field, pushing it into a short int in tree_base
>>>> (hopefully 2^16 non-defaulted template args are enough ...).
>>> Honestly, I don't think it's a trivial issue.
>>
>> Love to hear from Jason, but, my take would be 2^16 should be enough for anyone.  I think long before people hit that limit, they would merely aggregate arguments into classes and structures.  I think in another 20-80 years, we might want to bump it back up to 32 bits, but...  I think we can safely wait until we get a compelling bug report for it.
>
> C++11 says that an implementation should be able to handle at least 2^10
> template parameters, 2^12 members declared in a single class.  I believe
> that even for automatically generated programs, 2^16 is a good limit.  I suspect
> that by the time that limit is a hindrance, C++ would have gone through several
> iterations and more importantly 128-bit integers would be common place, so
> by that time we would have plenty of spare bits -- if we haven't already
> restructured the tree data structures to use idiomatic C++ constructs that
> are both more space and time efficient.
>
> This is a very long of saying "I am comfortable with the 2^16 restriction
> on the number of template parameters.  The patch needs to document
> that in the usual .texi file."

I searched for a place where we document GNU C++ implmenetation
defined behavior / limits
but didn't find it.  Can you point me to the place where we document
that the current
limit is 2^31 - 1 _non defaulted_ template parameters?  (It looks to
me this whole
non-defaulted-template-args stuff was just invented to avoid
pretty-printing defaulted args,
so it does not in any way present an implementation limit but only a
possible bug in that
we'd never pretty-print more than 2^31 - 1 non-defaulted template
paramters in a diagnostic,
but who wants to see 2^31 template parameters in a diagnostic anyways ...)

Richard.

> -- Gaby

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

* Re: [PATCH][C++] Get rid of TREE_CHAIN use for TREE_VEC (NON_DEFAULT_TEMPLATE_ARGS_COUNT)
  2012-08-17 19:11     ` Gabriel Dos Reis
  2012-08-18  7:39       ` Richard Guenther
@ 2012-08-18  8:55       ` Paolo Carlini
  1 sibling, 0 replies; 7+ messages in thread
From: Paolo Carlini @ 2012-08-18  8:55 UTC (permalink / raw)
  To: Gabriel Dos Reis, Mike Stump; +Cc: Richard Guenther, gcc-patches, Jason Merrill

Gabriel Dos Reis <gdr@integrable-solutions.net> ha scritto:

>C++11 says that an implementation should be able to handle at least
>2^10
>template parameters, 2^12 members declared in a single class.

Thanks a lot Gaby for pointing out this, I overlooked it.

Paolo

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

* Re: [PATCH][C++] Get rid of TREE_CHAIN use for TREE_VEC (NON_DEFAULT_TEMPLATE_ARGS_COUNT)
  2012-08-17 11:29 [PATCH][C++] Get rid of TREE_CHAIN use for TREE_VEC (NON_DEFAULT_TEMPLATE_ARGS_COUNT) Richard Guenther
  2012-08-17 13:58 ` Paolo Carlini
@ 2012-08-20 10:50 ` Richard Guenther
  1 sibling, 0 replies; 7+ messages in thread
From: Richard Guenther @ 2012-08-20 10:50 UTC (permalink / raw)
  To: gcc-patches

On Fri, 17 Aug 2012, Richard Guenther wrote:

> 
> This gets rid of this field, pushing it into a short int in tree_base
> (hopefully 2^16 non-defaulted template args are enough ...).  The
> existing code is a bit confusing because of the differences with
> respect to ENABLE_CHECKING, it has very little testcase coverage as
> well (a single testcase, g++.dg/template/error39.C), so I am not sure
> I got the idea correct (especially as ENABLE_CHECKING vs. 
> non-ENABLE_CHECKING looks to introduce subtle differences?).
> 
> Anyway, a previous iteration that failed g++.dg/template/error39.C
> bootstrapped and tested all languages ok, the following version now
> passes g++.dg/template/error39.C and hopefully bootstrap and regtest
> as well.
> 
> We build a _lot_ of TREE_VECs from the C++ frontend, so this 8 byte
> saving is quite visible.  TREE_VEC is the most used TREE_CODE by far
> on PR54146:
> 
> ...
> ssa_name              363597
> mem_ref               403966
> addr_expr            1203839
> tree_list            1205721
> tree_vec             2654415
> 
> which translates to 109615896 bytes allocated in TREE_VECs (yes,
> that includes the actual storage, the average size is 41.3 bytes,
> with this patch TREE_VEC itself shrinks from 40 bytes to 32 bytes
> which means the average TREE_VEC size is one!).
> 
> Let's hope removing TREE_TYPE from TREE_VEC is as "easy" ;)

It turns out the C++ frontend is again the only user.  It gets
used for DECL_PRIMARY_TEMPLATE.  Now, the C++ fronend indeed seems
to want to associate information with the template argument vector
itself, not the template.  As the patch removing TREE_CAHIN is in
some sense not an improvement (C++ specific bits remain in the
generic tree structure, blocking from the VEC size being moved
to spare bits in tree_base), the DECL_PRIMARY_TEMPLATE usage shows
that using a TREE_VEC to represent the template argument is the
issue.  We cannot simply derive from TREE_VEC because it relies
on storage allocated at its tail, so instead a C++ specific tree
node mimicking a TREE_VEC but sporting extra fields, including
ones for the number of non-defaulted args and for DECL_PRIMARY_TEMPLATE
would be the way to go.  That node would derive from tree_base.

This should be pretty straight-forward to do, but I'll push it
back for now due to lack of time.  So consider this patch
withdrawn.  You'll instead see me trying to move the length
field into tree_base.

Richard.

> Re-bootstrap and regtest running on x86_64-unknown-linux-gnu.
> 
> Ok for the C++ parts?
> 
> Thanks,
> Richard.
> 
> 2012-08-17  Richard Guenther  <rguenther@suse.de>
> 
> 	* tree.h (struct tree_base): Put address_space into a union,
> 	alongside a new field non_default_template_args_count used by
> 	C++ TREE_VECs.
> 	(struct tree_vec): Derive from tree_typed instead of tree_common.
> 	(TYPE_ADDR_SPACE): Adjust.
> 	* tree.c (initialize_tree_contains_struct): Adjust tree type
> 	hierarchy.
> 
> 	cp/
> 	* cp-tree.h (NON_DEFAULT_TEMPLATE_ARGS_COUNT): Remove.
> 	(SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT,
> 	GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT): Use
> 	non_default_template_args_count in tree_base instead of TREE_CHAIN.
> 	* pt.c (expand_template_argument_pack): Adjust.
> 	(template_parm_to_arg): Likewise.
> 	(current_template_args): Likewise.
> 	(coerce_template_parameter_pack): Likewise.
> 	(coerce_template_parms): Likewise.
> 	(tsubst_template_args): Likewise.
> 	(type_unification_real): Likewise.
> 	* parser.c (cp_parser_template_argument_list): Likewise.
> 
> Index: gcc/tree.h
> ===================================================================
> *** gcc/tree.h	(revision 190469)
> --- gcc/tree.h	(working copy)
> *************** struct GTY(()) tree_base {
> *** 453,465 ****
>     unsigned packed_flag : 1;
>     unsigned user_align : 1;
>     unsigned nameless_flag : 1;
>   
> !   unsigned spare : 12;
> ! 
> !   /* This field is only used with type nodes; the only reason it is present
> !      in tree_base instead of tree_type is to save space.  The size of the
> !      field must be large enough to hold addr_space_t values.  */
> !   unsigned address_space : 8;
>   };
>   
>   struct GTY(()) tree_typed {
> --- 453,473 ----
>     unsigned packed_flag : 1;
>     unsigned user_align : 1;
>     unsigned nameless_flag : 1;
> +   unsigned spare0 : 4;
>   
> !   /* The following has to be at a 16-bit alignment boundary to be properly
> !      packed and not make tree_base larger than 64 bits.  */
> !   union tree_base_spare_bits {
> !     /* This field is only used with type nodes; the only reason it is present
> !        in tree_base instead of tree_type is to save space.  The size of the
> !        field must be large enough to hold addr_space_t values.  */
> !     unsigned char address_space;
> ! 
> !     /* This field is only used with tree_vec nodes by the C++ frontend; the
> !        only reason it is present in tree_base instead of tree_vec is to
> !        save space.  */
> !     unsigned short non_default_template_args_count;
> !   } GTY((skip(""))) spare;
>   };
>   
>   struct GTY(()) tree_typed {
> *************** struct GTY(()) tree_list {
> *** 1483,1489 ****
>   #define TREE_VEC_ELT(NODE,I) TREE_VEC_ELT_CHECK (NODE, I)
>   
>   struct GTY(()) tree_vec {
> !   struct tree_common common;
>     int length;
>     tree GTY ((length ("TREE_VEC_LENGTH ((tree)&%h)"))) a[1];
>   };
> --- 1491,1497 ----
>   #define TREE_VEC_ELT(NODE,I) TREE_VEC_ELT_CHECK (NODE, I)
>   
>   struct GTY(()) tree_vec {
> !   struct tree_typed typed;
>     int length;
>     tree GTY ((length ("TREE_VEC_LENGTH ((tree)&%h)"))) a[1];
>   };
> *************** extern enum machine_mode vector_type_mod
> *** 2182,2188 ****
>   #define TYPE_NAMELESS(NODE) (TYPE_CHECK (NODE)->base.nameless_flag)
>   
>   /* The address space the type is in.  */
> ! #define TYPE_ADDR_SPACE(NODE) (TYPE_CHECK (NODE)->base.address_space)
>   
>   /* There is a TYPE_QUAL value for each type qualifier.  They can be
>      combined by bitwise-or to form the complete set of qualifiers for a
> --- 2190,2196 ----
>   #define TYPE_NAMELESS(NODE) (TYPE_CHECK (NODE)->base.nameless_flag)
>   
>   /* The address space the type is in.  */
> ! #define TYPE_ADDR_SPACE(NODE) (TYPE_CHECK (NODE)->base.spare.address_space)
>   
>   /* There is a TYPE_QUAL value for each type qualifier.  They can be
>      combined by bitwise-or to form the complete set of qualifiers for a
> Index: gcc/tree.c
> ===================================================================
> *** gcc/tree.c	(revision 190469)
> --- gcc/tree.c	(working copy)
> *************** initialize_tree_contains_struct (void)
> *** 382,387 ****
> --- 382,388 ----
>   	case TS_REAL_CST:
>   	case TS_FIXED_CST:
>   	case TS_VECTOR:
> + 	case TS_VEC:
>   	case TS_STRING:
>   	case TS_COMPLEX:
>   	case TS_SSA_NAME:
> *************** initialize_tree_contains_struct (void)
> *** 395,401 ****
>   	case TS_DECL_MINIMAL:
>   	case TS_TYPE_COMMON:
>   	case TS_LIST:
> - 	case TS_VEC:
>   	case TS_BINFO:
>   	case TS_OMP_CLAUSE:
>   	case TS_OPTIMIZATION:
> --- 396,401 ----
> Index: gcc/cp/pt.c
> ===================================================================
> *** gcc/cp/pt.c	(revision 190469)
> --- gcc/cp/pt.c	(working copy)
> *************** expand_template_argument_pack (tree args
> *** 3301,3307 ****
>     tree result_args = NULL_TREE;
>     int in_arg, out_arg = 0, nargs = args ? TREE_VEC_LENGTH (args) : 0;
>     int num_result_args = -1;
> !   int non_default_args_count = -1;
>   
>     /* First, determine if we need to expand anything, and the number of
>        slots we'll need.  */
> --- 3301,3307 ----
>     tree result_args = NULL_TREE;
>     int in_arg, out_arg = 0, nargs = args ? TREE_VEC_LENGTH (args) : 0;
>     int num_result_args = -1;
> !   int non_default_args_count;
>   
>     /* First, determine if we need to expand anything, and the number of
>        slots we'll need.  */
> *************** expand_template_argument_pack (tree args
> *** 3331,3339 ****
>   
>     /* Expand arguments.  */
>     result_args = make_tree_vec (num_result_args);
> !   if (NON_DEFAULT_TEMPLATE_ARGS_COUNT (args))
> !     non_default_args_count =
> !       GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args);
>     for (in_arg = 0; in_arg < nargs; ++in_arg)
>       {
>         tree arg = TREE_VEC_ELT (args, in_arg);
> --- 3331,3337 ----
>   
>     /* Expand arguments.  */
>     result_args = make_tree_vec (num_result_args);
> !   non_default_args_count = GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args);
>     for (in_arg = 0; in_arg < nargs; ++in_arg)
>       {
>         tree arg = TREE_VEC_ELT (args, in_arg);
> *************** expand_template_argument_pack (tree args
> *** 3343,3350 ****
>             int i, num_packed = TREE_VEC_LENGTH (packed);
>             for (i = 0; i < num_packed; ++i, ++out_arg)
>               TREE_VEC_ELT (result_args, out_arg) = TREE_VEC_ELT(packed, i);
> ! 	  if (non_default_args_count > 0)
> ! 	    non_default_args_count += num_packed;
>           }
>         else
>           {
> --- 3341,3347 ----
>             int i, num_packed = TREE_VEC_LENGTH (packed);
>             for (i = 0; i < num_packed; ++i, ++out_arg)
>               TREE_VEC_ELT (result_args, out_arg) = TREE_VEC_ELT(packed, i);
> ! 	  non_default_args_count += num_packed;
>           }
>         else
>           {
> *************** expand_template_argument_pack (tree args
> *** 3352,3359 ****
>             ++out_arg;
>           }
>       }
> !   if (non_default_args_count >= 0)
> !     SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (result_args, non_default_args_count);
>     return result_args;
>   }
>   
> --- 3349,3355 ----
>             ++out_arg;
>           }
>       }
> !   SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (result_args, non_default_args_count);
>     return result_args;
>   }
>   
> *************** template_parm_to_arg (tree t)
> *** 3702,3711 ****
>   	  /* Turn this argument into a TYPE_ARGUMENT_PACK
>   	     with a single element, which expands T.  */
>   	  tree vec = make_tree_vec (1);
> ! #ifdef ENABLE_CHECKING
> ! 	  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
> ! 	    (vec, TREE_VEC_LENGTH (vec));
> ! #endif
>   	  TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
>   
>   	  t = cxx_make_type (TYPE_ARGUMENT_PACK);
> --- 3698,3704 ----
>   	  /* Turn this argument into a TYPE_ARGUMENT_PACK
>   	     with a single element, which expands T.  */
>   	  tree vec = make_tree_vec (1);
> ! 	  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
>   	  TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
>   
>   	  t = cxx_make_type (TYPE_ARGUMENT_PACK);
> *************** template_parm_to_arg (tree t)
> *** 3722,3731 ****
>   	     with a single element, which expands T.  */
>   	  tree vec = make_tree_vec (1);
>   	  tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t));
> ! #ifdef ENABLE_CHECKING
> ! 	  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT
> ! 	    (vec, TREE_VEC_LENGTH (vec));
> ! #endif
>   	  TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
>   
>   	  t  = make_node (NONTYPE_ARGUMENT_PACK);
> --- 3715,3721 ----
>   	     with a single element, which expands T.  */
>   	  tree vec = make_tree_vec (1);
>   	  tree type = TREE_TYPE (TEMPLATE_PARM_DECL (t));
> ! 	  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
>   	  TREE_VEC_ELT (vec, 0) = make_pack_expansion (t);
>   
>   	  t  = make_node (NONTYPE_ARGUMENT_PACK);
> *************** current_template_args (void)
> *** 3800,3808 ****
>         for (i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i)
>   	TREE_VEC_ELT (a, i) = template_parm_to_arg (TREE_VEC_ELT (a, i));
>   
> - #ifdef ENABLE_CHECKING
>         SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (a, TREE_VEC_LENGTH (a));
> - #endif
>   
>         if (length > 1)
>   	TREE_VEC_ELT (args, --l) = a;
> --- 3790,3796 ----
> *************** coerce_template_parameter_pack (tree par
> *** 6410,6419 ****
>       }
>   
>     SET_ARGUMENT_PACK_ARGS (argument_pack, packed_args);
> - #ifdef ENABLE_CHECKING
>     SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (packed_args,
>   				       TREE_VEC_LENGTH (packed_args));
> - #endif
>     return argument_pack;
>   }
>   
> --- 6398,6405 ----
> *************** coerce_template_parms (tree parms,
> *** 6457,6462 ****
> --- 6443,6449 ----
>     tree new_inner_args;
>     int saved_unevaluated_operand;
>     int saved_inhibit_evaluation_warnings;
> +   bool defaulted_arg_found;
>   
>     /* When used as a boolean value, indicates whether this is a
>        variadic template parameter list. Since it's an int, we can also
> *************** coerce_template_parms (tree parms,
> *** 6528,6533 ****
> --- 6515,6521 ----
>     c_inhibit_evaluation_warnings = 0;
>     new_inner_args = make_tree_vec (nparms);
>     new_args = add_outermost_template_args (args, new_inner_args);
> +   defaulted_arg_found = false;
>     for (parm_idx = 0, arg_idx = 0; parm_idx < nparms; parm_idx++, arg_idx++)
>       {
>         tree arg;
> *************** coerce_template_parms (tree parms,
> *** 6586,6593 ****
>   	  /* The position of the first default template argument,
>   	     is also the number of non-defaulted arguments in NEW_INNER_ARGS.
>   	     Record that.  */
> ! 	  if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
> ! 	    SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args, arg_idx);
>   	}
>         else
>   	break;
> --- 6574,6584 ----
>   	  /* The position of the first default template argument,
>   	     is also the number of non-defaulted arguments in NEW_INNER_ARGS.
>   	     Record that.  */
> ! 	  if (!defaulted_arg_found)
> ! 	    {
> ! 	      defaulted_arg_found = true;
> ! 	      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args, arg_idx);
> ! 	    }
>   	}
>         else
>   	break;
> *************** coerce_template_parms (tree parms,
> *** 6619,6629 ****
>     if (lost)
>       return error_mark_node;
>   
> ! #ifdef ENABLE_CHECKING
> !   if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
>       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,
>   					 TREE_VEC_LENGTH (new_inner_args));
> - #endif
>   
>     return new_inner_args;
>   }
> --- 6610,6618 ----
>     if (lost)
>       return error_mark_node;
>   
> !   if (!defaulted_arg_found)
>       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,
>   					 TREE_VEC_LENGTH (new_inner_args));
>   
>     return new_inner_args;
>   }
> *************** tsubst_template_args (tree t, tree args,
> *** 9393,9404 ****
>        It will rather be the nested TREE_VECs that will carry one.
>        In other words, ORIG_T carries a non defaulted argument count only
>        if it doesn't contain any nested TREE_VEC.  */
> !   if (NON_DEFAULT_TEMPLATE_ARGS_COUNT (orig_t))
> !     {
> !       int count = GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (orig_t);
> !       count += expanded_len_adjust;
> !       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (t, count);
> !     }
>     for (i = 0, out = 0; i < len; i++)
>       {
>         if ((PACK_EXPANSION_P (TREE_VEC_ELT (orig_t, i))
> --- 9382,9390 ----
>        It will rather be the nested TREE_VECs that will carry one.
>        In other words, ORIG_T carries a non defaulted argument count only
>        if it doesn't contain any nested TREE_VEC.  */
> !   int count = GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (orig_t);
> !   count += expanded_len_adjust;
> !   SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (t, count);
>     for (i = 0, out = 0; i < len; i++)
>       {
>         if ((PACK_EXPANSION_P (TREE_VEC_ELT (orig_t, i))
> *************** type_unification_real (tree tparms,
> *** 14982,14995 ****
>     const tree *args;
>     unsigned int nargs;
>     unsigned int ia;
>   
>     gcc_assert (TREE_CODE (tparms) == TREE_VEC);
>     gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
>     gcc_assert (ntparms > 0);
>   
> !   /* Reset the number of non-defaulted template arguments contained
> !      in TARGS.  */
> !   NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs) = NULL_TREE;
>   
>    again:
>     parms = xparms;
> --- 14968,14981 ----
>     const tree *args;
>     unsigned int nargs;
>     unsigned int ia;
> +   bool defaulted_arg_found;
>   
>     gcc_assert (TREE_CODE (tparms) == TREE_VEC);
>     gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
>     gcc_assert (ntparms > 0);
>   
> !   /* Note that we did not yet find a defaulted template argument.  */
> !   defaulted_arg_found = false;
>   
>    again:
>     parms = xparms;
> *************** type_unification_real (tree tparms,
> *** 15140,15147 ****
>   		  /* The position of the first default template argument,
>   		     is also the number of non-defaulted arguments in TARGS.
>   		     Record that.  */
> ! 		  if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
> ! 		    SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
>   		  continue;
>   		}
>   	    }
> --- 15126,15136 ----
>   		  /* The position of the first default template argument,
>   		     is also the number of non-defaulted arguments in TARGS.
>   		     Record that.  */
> ! 		  if (!defaulted_arg_found)
> ! 		    {
> ! 		      defaulted_arg_found = true;
> ! 		      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, i);
> ! 		    }
>   		  continue;
>   		}
>   	    }
> *************** type_unification_real (tree tparms,
> *** 15170,15179 ****
>   	  return unify_parameter_deduction_failure (explain_p, tparm);
>   	}
>       }
> ! #ifdef ENABLE_CHECKING
> !   if (!NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs))
>       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs));
> - #endif
>   
>     return unify_success (explain_p);
>   }
> --- 15159,15166 ----
>   	  return unify_parameter_deduction_failure (explain_p, tparm);
>   	}
>       }
> !   if (!defaulted_arg_found)
>       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs));
>   
>     return unify_success (explain_p);
>   }
> Index: gcc/cp/cp-tree.h
> ===================================================================
> *** gcc/cp/cp-tree.h	(revision 190469)
> --- gcc/cp/cp-tree.h	(working copy)
> *************** extern void decl_shadowed_for_var_insert
> *** 2661,2681 ****
>   #define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
>   /* For a given TREE_VEC containing a template argument list,
>      this property contains the number of arguments that are not
> !    defaulted.  */
> ! #define NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) TREE_CHAIN (TREE_VEC_CHECK (NODE))
> ! /* Below are the setter and getter of the NON_DEFAULT_TEMPLATE_ARGS_COUNT
>      property.  */
>   #define SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE, INT_VALUE) \
> !   NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) = build_int_cst (NULL_TREE, INT_VALUE)
> ! #ifdef ENABLE_CHECKING
>   #define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
> !     int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE))
> ! #else
> ! #define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
> !   NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE) \
> !   ? int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE)) \
> !   : TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (NODE))
> ! #endif
>   /* The list of typedefs - used in the template - that need
>      access checking at template instantiation time.  */
>   #define TI_TYPEDEFS_NEEDING_ACCESS_CHECKING(NODE) \
> --- 2661,2673 ----
>   #define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
>   /* For a given TREE_VEC containing a template argument list,
>      this property contains the number of arguments that are not
> !    defaulted.  The following are the setter and getter of this
>      property.  */
>   #define SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE, INT_VALUE) \
> !   TREE_VEC_CHECK (NODE)->base.spare.non_default_template_args_count \
> !     = (INT_VALUE)
>   #define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \
> !   ((int) TREE_VEC_CHECK (NODE)->base.spare.non_default_template_args_count)
>   /* The list of typedefs - used in the template - that need
>      access checking at template instantiation time.  */
>   #define TI_TYPEDEFS_NEEDING_ACCESS_CHECKING(NODE) \
> Index: gcc/cp/parser.c
> ===================================================================
> *** gcc/cp/parser.c	(revision 190469)
> --- gcc/cp/parser.c	(working copy)
> *************** cp_parser_template_argument_list (cp_par
> *** 12855,12863 ****
>     parser->non_integral_constant_expression_p = saved_non_ice_p;
>     parser->integral_constant_expression_p = saved_ice_p;
>     parser->in_template_argument_list_p = saved_in_template_argument_list_p;
> - #ifdef ENABLE_CHECKING
>     SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
> - #endif
>     return vec;
>   }
>   
> --- 12855,12861 ----
> 

-- 
Richard Guenther <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend

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

end of thread, other threads:[~2012-08-20 10:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-17 11:29 [PATCH][C++] Get rid of TREE_CHAIN use for TREE_VEC (NON_DEFAULT_TEMPLATE_ARGS_COUNT) Richard Guenther
2012-08-17 13:58 ` Paolo Carlini
2012-08-17 18:03   ` Mike Stump
2012-08-17 19:11     ` Gabriel Dos Reis
2012-08-18  7:39       ` Richard Guenther
2012-08-18  8:55       ` Paolo Carlini
2012-08-20 10:50 ` Richard Guenther

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