Re: [PATCH] less build_function_type usage in the Fortran FE

2011-05-04 Thread Tobias Burnus

On 05/03/2011 09:06 PM, Nathan Froyd wrote:

Testing in progress on x86_64-unknown-linux-gnu.  OK to commit if
testing successful?


The Fortran part is OK. Thanks for the janitorial work.

Tobias


gcc/
* tree.h (build_function_type_array): Declare.
(build_varargs_function_type_array): Declare.
(build_function_type_vec, build_varargs_function_type_vec): Define.
* tree.c (build_function_type_array_1): New function.
(build_function_type_array): New function.
(build_varargs_function_type_array): New function.

gcc/fortran/
* trans-decl.c (build_library_function_decl_1): Call
build_function_type_vec.  Adjust argument list building accordingly.
* trans-intrinsic.c (gfc_get_intrinsic_lib_fndecl): Likewise.
* trans-types.c (gfc_get_function_type): Likewise.


Re: [PATCH] less build_function_type usage in the Fortran FE

2011-05-04 Thread Richard Guenther
On Wed, May 4, 2011 at 11:22 AM, Tobias Burnus bur...@net-b.de wrote:
 On 05/03/2011 09:06 PM, Nathan Froyd wrote:

 Testing in progress on x86_64-unknown-linux-gnu.  OK to commit if
 testing successful?

 The Fortran part is OK. Thanks for the janitorial work.

The middle-end parts are also ok.

Richard.

 Tobias

 gcc/
        * tree.h (build_function_type_array): Declare.
        (build_varargs_function_type_array): Declare.
        (build_function_type_vec, build_varargs_function_type_vec): Define.
        * tree.c (build_function_type_array_1): New function.
        (build_function_type_array): New function.
        (build_varargs_function_type_array): New function.

 gcc/fortran/
        * trans-decl.c (build_library_function_decl_1): Call
        build_function_type_vec.  Adjust argument list building
 accordingly.
        * trans-intrinsic.c (gfc_get_intrinsic_lib_fndecl): Likewise.
        * trans-types.c (gfc_get_function_type): Likewise.



Re: [PATCH] less build_function_type usage in the Fortran FE

2011-05-04 Thread Nathan Froyd
On Wed, May 04, 2011 at 11:22:02AM +0200, Tobias Burnus wrote:
 On 05/03/2011 09:06 PM, Nathan Froyd wrote:
 Testing in progress on x86_64-unknown-linux-gnu.  OK to commit if
 testing successful?

 The Fortran part is OK. Thanks for the janitorial work.

Thanks for the review!  We'll see if the janitorial work actually leads
to something useful later on. :)

I've committed the patch below as r173375; testing showed a couple
failures.  I had originally changed this bit in trans-types.c:

  if (typelist)
typelist = chainon (typelist, void_list_node);
  else if (sym-attr.is_main_program || sym-attr.if_source != IFSRC_UNKNOWN)
typelist = void_list_node;

to this:

  if (typelist)
is_varargs = false;
  else if (sym-attr.is_main_program || sym-attr.if_source != IFSRC_UNKNOWN)
{
  VEC_free (tree, gc, typelist);
  typelist = NULL;
}

Except that change makes the 'else if' case create a varargs function
where we weren't before.  The VEC_free is totally pointless there,
because typelist would be NULL anyway.  And we ought to be testing with
VEC_empty instead.  A little thought shows that:

  if (!VEC_empty (tree, typelist)
  || sym-attr.is_main_program
  || sym-attr.if_source != IFSRC_UNKNOWN)
is_varargs = false;

is what we really want.

-Nathan

gcc/
* tree.h (build_function_type_array): Declare.
(build_varargs_function_type_array): Declare.
(build_function_type_vec, build_varargs_function_type_vec):
Define.
* tree.c (build_function_type_array_1): New function.
(build_function_type_array): New function.
(build_varargs_function_type_array): New function.

gcc/fortran/
* trans-decl.c (build_library_function_decl_1): Call
build_function_type_vec.  Adjust argument list building
accordingly.
* trans-intrinsic.c (gfc_get_intrinsic_lib_fndecl): Likewise.
* trans-types.c (gfc_get_function_type): Likewise.

diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index f80c9db..dc381f9 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -2478,8 +2478,7 @@ static tree
 build_library_function_decl_1 (tree name, const char *spec,
   tree rettype, int nargs, va_list p)
 {
-  tree arglist;
-  tree argtype;
+  VEC(tree,gc) *arglist;
   tree fntype;
   tree fndecl;
   int n;
@@ -2488,20 +2487,18 @@ build_library_function_decl_1 (tree name, const char 
*spec,
   gcc_assert (current_function_decl == NULL_TREE);
 
   /* Create a list of the argument types.  */
-  for (arglist = NULL_TREE, n = abs (nargs); n  0; n--)
+  arglist = VEC_alloc (tree, gc, abs (nargs));
+  for (n = abs (nargs); n  0; n--)
 {
-  argtype = va_arg (p, tree);
-  arglist = gfc_chainon_list (arglist, argtype);
-}
-
-  if (nargs = 0)
-{
-  /* Terminate the list.  */
-  arglist = chainon (arglist, void_list_node);
+  tree argtype = va_arg (p, tree);
+  VEC_quick_push (tree, arglist, argtype);
 }
 
   /* Build the function type and decl.  */
-  fntype = build_function_type (rettype, arglist);
+  if (nargs = 0)
+fntype = build_function_type_vec (rettype, arglist);
+  else
+fntype = build_varargs_function_type_vec (rettype, arglist);
   if (spec)
 {
   tree attr_args = build_tree_list (NULL_TREE,
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 10dadf7..bbbf64f 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -722,7 +722,7 @@ static tree
 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
 {
   tree type;
-  tree argtypes;
+  VEC(tree,gc) *argtypes;
   tree fndecl;
   gfc_actual_arglist *actual;
   tree *pdecl;
@@ -803,14 +803,13 @@ gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, 
gfc_expr * expr)
ts-kind);
 }
 
-  argtypes = NULL_TREE;
+  argtypes = NULL;
   for (actual = expr-value.function.actual; actual; actual = actual-next)
 {
   type = gfc_typenode_for_spec (actual-expr-ts);
-  argtypes = gfc_chainon_list (argtypes, type);
+  VEC_safe_push (tree, gc, argtypes, type);
 }
-  argtypes = chainon (argtypes, void_list_node);
-  type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
+  type = build_function_type_vec (gfc_typenode_for_spec (ts), argtypes);
   fndecl = build_decl (input_location,
   FUNCTION_DECL, get_identifier (name), type);
 
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index 27dcf82..cc82037 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -2534,10 +2534,11 @@ tree
 gfc_get_function_type (gfc_symbol * sym)
 {
   tree type;
-  tree typelist;
+  VEC(tree,gc) *typelist;
   gfc_formal_arglist *f;
   gfc_symbol *arg;
   int alternate_return;
+  bool is_varargs = true;
 
   /* Make sure this symbol is a function, a subroutine or the main
  program.  */
@@ -2548,13 +2549,11 @@ gfc_get_function_type 

[PATCH] less build_function_type usage in the Fortran FE

2011-05-03 Thread Nathan Froyd
The patch below eliminates almost all cases of build_function_type in
the Fortran FE.  (The last case uses TYPE_ARG_TYPES directly and will
need to be dealt with separately.)  This is accomplished by introducing
two new functions, build_{,varargs_}function_type_array, which do what
you think, and two small macro wrappers around them,
build_{,varargs_}function_type_vec.  The macro wrappers are used so that
one can use heap-, gc-, or stack-allocated vectors, as necessary.

Comments on the middle-end bits welcome; some sort of FUNCTION_TYPE
builder with a dynamically determined number of argument types is needed
for working towards the elimination of TYPE_ARG_TYPES.

As a happy side-effect, the patch eliminates uses of gfc_chainon_list
and makes the specific instances below of building function types
linear, instead of quadratic.  If the patch is approved, I will delete
gfc_chainon_list as an obvious followon patch.

Testing in progress on x86_64-unknown-linux-gnu.  OK to commit if
testing successful?

-Nathan

gcc/
* tree.h (build_function_type_array): Declare.
(build_varargs_function_type_array): Declare.
(build_function_type_vec, build_varargs_function_type_vec): Define.
* tree.c (build_function_type_array_1): New function.
(build_function_type_array): New function.
(build_varargs_function_type_array): New function.

gcc/fortran/
* trans-decl.c (build_library_function_decl_1): Call
build_function_type_vec.  Adjust argument list building accordingly.
* trans-intrinsic.c (gfc_get_intrinsic_lib_fndecl): Likewise.
* trans-types.c (gfc_get_function_type): Likewise.

diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index f80c9db..dc381f9 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -2478,8 +2478,7 @@ static tree
 build_library_function_decl_1 (tree name, const char *spec,
   tree rettype, int nargs, va_list p)
 {
-  tree arglist;
-  tree argtype;
+  VEC(tree,gc) *arglist;
   tree fntype;
   tree fndecl;
   int n;
@@ -2488,20 +2487,18 @@ build_library_function_decl_1 (tree name, const char 
*spec,
   gcc_assert (current_function_decl == NULL_TREE);
 
   /* Create a list of the argument types.  */
-  for (arglist = NULL_TREE, n = abs (nargs); n  0; n--)
+  arglist = VEC_alloc (tree, gc, abs (nargs));
+  for (n = abs (nargs); n  0; n--)
 {
-  argtype = va_arg (p, tree);
-  arglist = gfc_chainon_list (arglist, argtype);
-}
-
-  if (nargs = 0)
-{
-  /* Terminate the list.  */
-  arglist = chainon (arglist, void_list_node);
+  tree argtype = va_arg (p, tree);
+  VEC_quick_push (tree, arglist, argtype);
 }
 
   /* Build the function type and decl.  */
-  fntype = build_function_type (rettype, arglist);
+  if (nargs = 0)
+fntype = build_function_type_vec (rettype, arglist);
+  else
+fntype = build_varargs_function_type_vec (rettype, arglist);
   if (spec)
 {
   tree attr_args = build_tree_list (NULL_TREE,
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 180aba1..360723c 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -722,7 +722,7 @@ static tree
 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
 {
   tree type;
-  tree argtypes;
+  VEC(tree,gc) *argtypes;
   tree fndecl;
   gfc_actual_arglist *actual;
   tree *pdecl;
@@ -803,14 +803,13 @@ gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, 
gfc_expr * expr)
ts-kind);
 }
 
-  argtypes = NULL_TREE;
+  argtypes = NULL;
   for (actual = expr-value.function.actual; actual; actual = actual-next)
 {
   type = gfc_typenode_for_spec (actual-expr-ts);
-  argtypes = gfc_chainon_list (argtypes, type);
+  VEC_safe_push (tree, gc, argtypes, type);
 }
-  argtypes = chainon (argtypes, void_list_node);
-  type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
+  type = build_function_type_vec (gfc_typenode_for_spec (ts), argtypes);
   fndecl = build_decl (input_location,
   FUNCTION_DECL, get_identifier (name), type);
 
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index ebc8c23..4606f68 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -2534,10 +2534,11 @@ tree
 gfc_get_function_type (gfc_symbol * sym)
 {
   tree type;
-  tree typelist;
+  VEC(tree,gc) *typelist;
   gfc_formal_arglist *f;
   gfc_symbol *arg;
   int alternate_return;
+  bool is_varargs = true;
 
   /* Make sure this symbol is a function, a subroutine or the main
  program.  */
@@ -2548,13 +2549,11 @@ gfc_get_function_type (gfc_symbol * sym)
 return TREE_TYPE (sym-backend_decl);
 
   alternate_return = 0;
-  typelist = NULL_TREE;
+  typelist = NULL;
 
   if (sym-attr.entry_master)
-{
-  /* Additional parameter for selecting an entry point.  */
-  typelist = gfc_chainon_list (typelist,