Re: [PATCH] less build_function_type usage in the Fortran FE
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
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
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
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,