Patchwork get rid of some TYPE_ARG_TYPES usage by introducing nth_arg_type

login
register
mail settings
Submitter Nathan Froyd
Date May 23, 2011, 1:53 p.m.
Message ID <20110523135324.GA13949@nightcrawler>
Download mbox | patch
Permalink /patch/96944/
State New
Headers show

Comments

Nathan Froyd - May 23, 2011, 1:53 p.m.
Various places in the compiler grab TYPE_ARG_TYPES and grovel through it
when what they're really trying to do is index into the list of argument
types.  The patch below introduces nth_arg_type for such situatiosn and
changes a hodgepodge of places to use it.  You could, of course, use
function_args_iterator, but I think this approach is somewhat clearer.

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

-Nathan

gcc/
	* tree.h (nth_arg_type): Declare.
	* tree.c (nth_arg_type): Define.
	* dbxout.c (dbxout_type_method_1): Call it.
	* dwarf2out.c (decl_class_context): Likewise.
	* tree-ssa-math-opts.c (execute_optimize_bswap): Likewise.

gcc/cp/
	* cp-tree.h (DECL_CONST_MEMFUNC_P): Call nth_arg_type.
	(DECL_VOLATILE_MEMFUNC_P, type_of_this_parm): Likewise.

gcc/fortran/
	* trans-decl.c (create_main_function): Call nth_arg_type.

gcc/objc/
	* objc-next-runtime-abi-01.c (next_sjlj_build_enter_and_setjmp):
	Call nth_arg_type.
Richard Guenther - May 23, 2011, 2:05 p.m.
On Mon, May 23, 2011 at 3:53 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> Various places in the compiler grab TYPE_ARG_TYPES and grovel through it
> when what they're really trying to do is index into the list of argument
> types.  The patch below introduces nth_arg_type for such situatiosn and
> changes a hodgepodge of places to use it.  You could, of course, use
> function_args_iterator, but I think this approach is somewhat clearer.
>
> Tested on x86_64-unknown-linux-gnu.  OK to commit?

See below

> -Nathan
>
> gcc/
>        * tree.h (nth_arg_type): Declare.
>        * tree.c (nth_arg_type): Define.
>        * dbxout.c (dbxout_type_method_1): Call it.
>        * dwarf2out.c (decl_class_context): Likewise.
>        * tree-ssa-math-opts.c (execute_optimize_bswap): Likewise.
>
> gcc/cp/
>        * cp-tree.h (DECL_CONST_MEMFUNC_P): Call nth_arg_type.
>        (DECL_VOLATILE_MEMFUNC_P, type_of_this_parm): Likewise.
>
> gcc/fortran/
>        * trans-decl.c (create_main_function): Call nth_arg_type.
>
> gcc/objc/
>        * objc-next-runtime-abi-01.c (next_sjlj_build_enter_and_setjmp):
>        Call nth_arg_type.
>
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index ada01fb..53848c3 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -2256,15 +2256,13 @@ struct GTY((variable_size)) lang_decl {
>    has `this' as const X *const.  */
>  #define DECL_CONST_MEMFUNC_P(NODE)                                      \
>   (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)                              \
> -   && CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE                            \
> -                                 (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))
> +   && CP_TYPE_CONST_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0))))
>
>  /* Nonzero for FUNCTION_DECL means that this member function
>    has `this' as volatile X *const.  */
>  #define DECL_VOLATILE_MEMFUNC_P(NODE)                                   \
>   (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)                              \
> -   && CP_TYPE_VOLATILE_P (TREE_TYPE (TREE_VALUE                                 \
> -                                 (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))
> +   && CP_TYPE_VOLATILE_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0))))
>
>  /* Nonzero for a DECL means that this member is a non-static member.  */
>  #define DECL_NONSTATIC_MEMBER_P(NODE)          \
> @@ -4660,10 +4658,8 @@ struct GTY(()) tinst_level {
>  static inline tree
>  type_of_this_parm (const_tree fntype)
>  {
> -  function_args_iterator iter;
>   gcc_assert (TREE_CODE (fntype) == METHOD_TYPE);
> -  function_args_iter_init (&iter, fntype);
> -  return function_args_iter_cond (&iter);
> +  return nth_arg_type (fntype, 0);
>  }
>
>  /* Return the class of the `this' parameter of FNTYPE.  */
> diff --git a/gcc/dbxout.c b/gcc/dbxout.c
> index 3190803..f5e985e 100644
> --- a/gcc/dbxout.c
> +++ b/gcc/dbxout.c
> @@ -1585,7 +1585,7 @@ dbxout_type_method_1 (tree decl)
>     c2 = '?';
>   else /* it's a METHOD_TYPE.  */
>     {
> -      tree firstarg = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)));
> +      tree firstarg = nth_arg_type (TREE_TYPE (decl), 0);
>       /* A for normal functions.
>         B for `const' member functions.
>         C for `volatile' member functions.
> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
> index b85a55e..d95c3f4 100644
> --- a/gcc/dwarf2out.c
> +++ b/gcc/dwarf2out.c
> @@ -7484,7 +7484,7 @@ decl_class_context (tree decl)
>     context = DECL_CONTEXT (decl);
>   else
>     context = TYPE_MAIN_VARIANT
> -      (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));
> +      (TREE_TYPE (nth_arg_type (TREE_TYPE (decl), 0)));
>
>   if (context && !TYPE_P (context))
>     context = NULL_TREE;
> diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
> index d771484..19d3e03 100644
> --- a/gcc/fortran/trans-decl.c
> +++ b/gcc/fortran/trans-decl.c
> @@ -4518,7 +4518,7 @@ create_main_function (tree fndecl)
>  {
>   tree old_context;
>   tree ftn_main;
> -  tree tmp, decl, result_decl, argc, argv, typelist, arglist;
> +  tree tmp, decl, result_decl, argc, argv, fntype, arglist;
>   stmtblock_t body;
>
>   old_context = current_function_decl;
> @@ -4559,21 +4559,20 @@ create_main_function (tree fndecl)
>   /* Get the arguments.  */
>
>   arglist = NULL_TREE;
> -  typelist = TYPE_ARG_TYPES (TREE_TYPE (ftn_main));
> +  fntype = TREE_TYPE (ftn_main);
>
> -  tmp = TREE_VALUE (typelist);
> +  tmp = nth_arg_type (fntype, 0);
>   argc = build_decl (input_location, PARM_DECL, get_identifier ("argc"), tmp);
>   DECL_CONTEXT (argc) = ftn_main;
> -  DECL_ARG_TYPE (argc) = TREE_VALUE (typelist);
> +  DECL_ARG_TYPE (argc) = tmp;
>   TREE_READONLY (argc) = 1;
>   gfc_finish_decl (argc);
>   arglist = chainon (arglist, argc);
>
> -  typelist = TREE_CHAIN (typelist);
> -  tmp = TREE_VALUE (typelist);
> +  tmp = nth_arg_type (fntype, 1);
>   argv = build_decl (input_location, PARM_DECL, get_identifier ("argv"), tmp);
>   DECL_CONTEXT (argv) = ftn_main;
> -  DECL_ARG_TYPE (argv) = TREE_VALUE (typelist);
> +  DECL_ARG_TYPE (argv) = tmp;
>   TREE_READONLY (argv) = 1;
>   DECL_BY_REFERENCE (argv) = 1;
>   gfc_finish_decl (argv);
> diff --git a/gcc/objc/objc-next-runtime-abi-01.c b/gcc/objc/objc-next-runtime-abi-01.c
> index d5b795f..37b2b10 100644
> --- a/gcc/objc/objc-next-runtime-abi-01.c
> +++ b/gcc/objc/objc-next-runtime-abi-01.c
> @@ -2584,7 +2584,7 @@ next_sjlj_build_enter_and_setjmp (struct objc_try_context **ctcp)
>  #ifdef OBJCPLUS
>   /* Convert _setjmp argument to type that is expected.  */
>   if (prototype_p (TREE_TYPE (objc_setjmp_decl)))
> -    t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
> +    t = convert (nth_arg_type (TREE_TYPE (objc_setjmp_decl), 0), t);
>   else
>     t = convert (ptr_type_node, t);
>  #else
> diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
> index b9f631e..5e6feb1 100644
> --- a/gcc/tree-ssa-math-opts.c
> +++ b/gcc/tree-ssa-math-opts.c
> @@ -1181,13 +1181,13 @@ execute_optimize_bswap (void)
>   if (bswap32_p)
>     {
>       tree fndecl = built_in_decls[BUILT_IN_BSWAP32];
> -      bswap32_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
> +      bswap32_type = nth_arg_type (TREE_TYPE (fndecl), 0);
>     }
>
>   if (bswap64_p)
>     {
>       tree fndecl = built_in_decls[BUILT_IN_BSWAP64];
> -      bswap64_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
> +      bswap64_type = nth_arg_type (TREE_TYPE (fndecl), 0);
>     }
>
>   memset (&bswap_stats, 0, sizeof (bswap_stats));
> diff --git a/gcc/tree.c b/gcc/tree.c
> index 3357d84..2925e13 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -10704,6 +10704,29 @@ prototype_p (tree fntype)
>   return (t != NULL_TREE);
>  }
>
> +/* Return the Nth argument type from FNTYPE.  */
> +
> +tree
> +nth_arg_type (const_tree fntype, int n)
> +{
> +  function_args_iterator iter;
> +  tree t;
> +  int i;
> +
> +  gcc_assert (fntype != NULL_TREE);
> +  gcc_assert (n >= 0);

Please merge the asserts and do s/gcc_assert/gcc_checking_assert/

And if n should be >= 0 why not pass it in as unsigned?

The patch is ok with both changes.

Thanks,
Richard.

> +  i = 0;
> +  FOREACH_FUNCTION_ARGS (fntype, t, iter)
> +    {
> +      if (n == i)
> +       return t;
> +      i++;
> +    }
> +
> +  gcc_unreachable ();
> +}
> +
>  /* If BLOCK is inlined from an __attribute__((__artificial__))
>    routine, return pointer to location from where it has been
>    called.  */
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 805fe06..9788071 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -5074,6 +5074,7 @@ extern tree create_artificial_label (location_t);
>  extern const char *get_name (tree);
>  extern bool stdarg_p (const_tree);
>  extern bool prototype_p (tree);
> +extern tree nth_arg_type (const_tree, int);
>  extern bool is_typedef_decl (tree x);
>  extern bool typedef_variant_p (tree);
>  extern bool auto_var_in_fn_p (const_tree, const_tree);
>
Nathan Froyd - May 23, 2011, 2:12 p.m.
On 05/23/2011 10:05 AM, Richard Guenther wrote:
> On Mon, May 23, 2011 at 3:53 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
>> +/* Return the Nth argument type from FNTYPE.  */
>> +
>> +tree
>> +nth_arg_type (const_tree fntype, int n)
>> +{
>> +  function_args_iterator iter;
>> +  tree t;
>> +  int i;
>> +
>> +  gcc_assert (fntype != NULL_TREE);
>> +  gcc_assert (n >= 0);
> 
> Please merge the asserts and do s/gcc_assert/gcc_checking_assert/

Ack.

> And if n should be >= 0 why not pass it in as unsigned?

Consistency with all the other interfaces where n is logically unsigned but
passed in as int?

> The patch is ok with both changes.

Thanks for the review.

-Nathan
Jason Merrill - May 23, 2011, 2:29 p.m.
On 05/23/2011 09:53 AM, Nathan Froyd wrote:
>   #define DECL_CONST_MEMFUNC_P(NODE)					 \
>     (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)				 \
> -&&  CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE				 \
> -				  (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))
> +&&  CP_TYPE_CONST_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0))))

This should use class_of_this_parm.

>   /* Nonzero for FUNCTION_DECL means that this member function
>      has `this' as volatile X *const.  */
>   #define DECL_VOLATILE_MEMFUNC_P(NODE)					 \
>     (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)				 \
> -&&  CP_TYPE_VOLATILE_P (TREE_TYPE (TREE_VALUE				 \
> -				  (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))
> +&&  CP_TYPE_VOLATILE_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0))))

As should this.

Jason

Patch

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index ada01fb..53848c3 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2256,15 +2256,13 @@  struct GTY((variable_size)) lang_decl {
    has `this' as const X *const.  */
 #define DECL_CONST_MEMFUNC_P(NODE)					 \
   (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)				 \
-   && CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE				 \
-				  (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))
+   && CP_TYPE_CONST_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0))))
 
 /* Nonzero for FUNCTION_DECL means that this member function
    has `this' as volatile X *const.  */
 #define DECL_VOLATILE_MEMFUNC_P(NODE)					 \
   (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)				 \
-   && CP_TYPE_VOLATILE_P (TREE_TYPE (TREE_VALUE				 \
-				  (TYPE_ARG_TYPES (TREE_TYPE (NODE))))))
+   && CP_TYPE_VOLATILE_P (TREE_TYPE (nth_arg_type (TREE_TYPE (NODE), 0))))
 
 /* Nonzero for a DECL means that this member is a non-static member.  */
 #define DECL_NONSTATIC_MEMBER_P(NODE)		\
@@ -4660,10 +4658,8 @@  struct GTY(()) tinst_level {
 static inline tree
 type_of_this_parm (const_tree fntype)
 {
-  function_args_iterator iter;
   gcc_assert (TREE_CODE (fntype) == METHOD_TYPE);
-  function_args_iter_init (&iter, fntype);
-  return function_args_iter_cond (&iter);
+  return nth_arg_type (fntype, 0);
 }
 
 /* Return the class of the `this' parameter of FNTYPE.  */
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 3190803..f5e985e 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -1585,7 +1585,7 @@  dbxout_type_method_1 (tree decl)
     c2 = '?';
   else /* it's a METHOD_TYPE.  */
     {
-      tree firstarg = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)));
+      tree firstarg = nth_arg_type (TREE_TYPE (decl), 0);
       /* A for normal functions.
 	 B for `const' member functions.
 	 C for `volatile' member functions.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index b85a55e..d95c3f4 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -7484,7 +7484,7 @@  decl_class_context (tree decl)
     context = DECL_CONTEXT (decl);
   else
     context = TYPE_MAIN_VARIANT
-      (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));
+      (TREE_TYPE (nth_arg_type (TREE_TYPE (decl), 0)));
 
   if (context && !TYPE_P (context))
     context = NULL_TREE;
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index d771484..19d3e03 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -4518,7 +4518,7 @@  create_main_function (tree fndecl)
 {
   tree old_context;
   tree ftn_main;
-  tree tmp, decl, result_decl, argc, argv, typelist, arglist;
+  tree tmp, decl, result_decl, argc, argv, fntype, arglist;
   stmtblock_t body;
 
   old_context = current_function_decl;
@@ -4559,21 +4559,20 @@  create_main_function (tree fndecl)
   /* Get the arguments.  */
 
   arglist = NULL_TREE;
-  typelist = TYPE_ARG_TYPES (TREE_TYPE (ftn_main));
+  fntype = TREE_TYPE (ftn_main);
 
-  tmp = TREE_VALUE (typelist);
+  tmp = nth_arg_type (fntype, 0);
   argc = build_decl (input_location, PARM_DECL, get_identifier ("argc"), tmp);
   DECL_CONTEXT (argc) = ftn_main;
-  DECL_ARG_TYPE (argc) = TREE_VALUE (typelist);
+  DECL_ARG_TYPE (argc) = tmp;
   TREE_READONLY (argc) = 1;
   gfc_finish_decl (argc);
   arglist = chainon (arglist, argc);
 
-  typelist = TREE_CHAIN (typelist);
-  tmp = TREE_VALUE (typelist);
+  tmp = nth_arg_type (fntype, 1);
   argv = build_decl (input_location, PARM_DECL, get_identifier ("argv"), tmp);
   DECL_CONTEXT (argv) = ftn_main;
-  DECL_ARG_TYPE (argv) = TREE_VALUE (typelist);
+  DECL_ARG_TYPE (argv) = tmp;
   TREE_READONLY (argv) = 1;
   DECL_BY_REFERENCE (argv) = 1;
   gfc_finish_decl (argv);
diff --git a/gcc/objc/objc-next-runtime-abi-01.c b/gcc/objc/objc-next-runtime-abi-01.c
index d5b795f..37b2b10 100644
--- a/gcc/objc/objc-next-runtime-abi-01.c
+++ b/gcc/objc/objc-next-runtime-abi-01.c
@@ -2584,7 +2584,7 @@  next_sjlj_build_enter_and_setjmp (struct objc_try_context **ctcp)
 #ifdef OBJCPLUS
   /* Convert _setjmp argument to type that is expected.  */
   if (prototype_p (TREE_TYPE (objc_setjmp_decl)))
-    t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t);
+    t = convert (nth_arg_type (TREE_TYPE (objc_setjmp_decl), 0), t);
   else
     t = convert (ptr_type_node, t);
 #else
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index b9f631e..5e6feb1 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1181,13 +1181,13 @@  execute_optimize_bswap (void)
   if (bswap32_p)
     {
       tree fndecl = built_in_decls[BUILT_IN_BSWAP32];
-      bswap32_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
+      bswap32_type = nth_arg_type (TREE_TYPE (fndecl), 0);
     }
 
   if (bswap64_p)
     {
       tree fndecl = built_in_decls[BUILT_IN_BSWAP64];
-      bswap64_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
+      bswap64_type = nth_arg_type (TREE_TYPE (fndecl), 0);
     }
 
   memset (&bswap_stats, 0, sizeof (bswap_stats));
diff --git a/gcc/tree.c b/gcc/tree.c
index 3357d84..2925e13 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -10704,6 +10704,29 @@  prototype_p (tree fntype)
   return (t != NULL_TREE);
 }
 
+/* Return the Nth argument type from FNTYPE.  */
+
+tree
+nth_arg_type (const_tree fntype, int n)
+{
+  function_args_iterator iter;
+  tree t;
+  int i;
+
+  gcc_assert (fntype != NULL_TREE);
+  gcc_assert (n >= 0);
+
+  i = 0;
+  FOREACH_FUNCTION_ARGS (fntype, t, iter)
+    {
+      if (n == i)
+	return t;
+      i++;
+    }
+
+  gcc_unreachable ();
+}
+
 /* If BLOCK is inlined from an __attribute__((__artificial__))
    routine, return pointer to location from where it has been
    called.  */
diff --git a/gcc/tree.h b/gcc/tree.h
index 805fe06..9788071 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -5074,6 +5074,7 @@  extern tree create_artificial_label (location_t);
 extern const char *get_name (tree);
 extern bool stdarg_p (const_tree);
 extern bool prototype_p (tree);
+extern tree nth_arg_type (const_tree, int);
 extern bool is_typedef_decl (tree x);
 extern bool typedef_variant_p (tree);
 extern bool auto_var_in_fn_p (const_tree, const_tree);