public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] centralize builtin function type building
@ 2011-04-21 15:37 Nathan Froyd
  2011-04-21 15:54 ` Richard Guenther
  2011-04-22 19:28 ` Michael Meissner
  0 siblings, 2 replies; 6+ messages in thread
From: Nathan Froyd @ 2011-04-21 15:37 UTC (permalink / raw)
  To: gcc-patches

This patch does two things:

- centralizes some infrastructure for defining builtin function types
  for frontends by providing a common function that
  DEF_FUNCTION_TYPE_FOO macros can call; and

- in order to do that well, it also introduces
  build{,_varargs}_function_type_array for cases when
  build_function_type_list's interface doesn't work so well.

build_function_type_list could have been used instead, but it would lose
the error_mark_node handling provided in the C/C++/Ada/LTO frontends.
This new interface will be necessary for eliminating other uses of
build_function_type anyway.

It would have been easier to move all of the builtin-types stuff into
the middle-end, but Fortran doesn't use builtin-types.def.  Even if it
did, I suppose it's possible that some new front-end could have its own
set of builtin types, so I'm leaving things as they are.

The new functions can eliminate some of the games that were played with
the recent backend changes to use build_function_type_list; if this
patch is approved, I'll make the (currently uncommitted) patches that
could use build_function_type_array do so.

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

-Nathan

gcc/ada/
	* gcc-interface/utils.c (def_fn_type): Delete.
	(DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
	define_builtin_function_type.
	(DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
	(DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
	(DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
	(DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
	(DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.

gcc/c-family/:
	* c-common.c (def_fn_type): Delete.
	(DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
	define_builtin_function_type.
	(DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
	(DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
	(DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
	(DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
	(DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.

gcc/
	* tree.h (build_function_type_array): Declare.
	(build_varargs_function_type_array, define_builtin_function_type):
	Declare.
	* tree.c (build_function_type_array_1): Define.
	(build_function_type_array, build_varargs_function_type_array): Define.
	(define_builtin_function_type): Define.

gcc/fortran/
	* f95-lang.c (DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change
	to use define_builtin_function_type.
	(DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
	(DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
	(DEF_FUNCTION_TYPE_VAR_0): Likewise.

gcc/lto/
	* lto-lang.c (def_fn_type): Delete.
	(DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
	define_builtin_function_type.
	(DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
	(DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
	(DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
	(DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
	(DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.

diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 1031ee9..6eb136d 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -4952,47 +4952,6 @@ typedef enum c_builtin_type builtin_type;
 /* A temporary array used in communication with def_fn_type.  */
 static GTY(()) tree builtin_types[(int) BT_LAST + 1];
 
-/* A helper function for install_builtin_types.  Build function type
-   for DEF with return type RET and N arguments.  If VAR is true, then the
-   function should be variadic after those N arguments.
-
-   Takes special care not to ICE if any of the types involved are
-   error_mark_node, which indicates that said type is not in fact available
-   (see builtin_type_for_size).  In which case the function type as a whole
-   should be error_mark_node.  */
-
-static void
-def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
-{
-  tree args = NULL, t;
-  va_list list;
-  int i;
-
-  va_start (list, n);
-  for (i = 0; i < n; ++i)
-    {
-      builtin_type a = (builtin_type) va_arg (list, int);
-      t = builtin_types[a];
-      if (t == error_mark_node)
-	goto egress;
-      args = tree_cons (NULL_TREE, t, args);
-    }
-  va_end (list);
-
-  args = nreverse (args);
-  if (!var)
-    args = chainon (args, void_list_node);
-
-  t = builtin_types[ret];
-  if (t == error_mark_node)
-    goto egress;
-  t = build_function_type (t, args);
-
- egress:
-  builtin_types[def] = t;
-  va_end (list);
-}
-
 /* Build the builtin function types and install them in the builtin_types
    array for later use in builtin function decls.  */
 
@@ -5016,35 +4975,35 @@ install_builtin_function_types (void)
 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
   builtin_types[ENUM] = VALUE;
 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
-  def_fn_type (ENUM, RETURN, 0, 0);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 0);
 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
-  def_fn_type (ENUM, RETURN, 0, 1, ARG1);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 1, (int) ARG1);
 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
-  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 2, (int) ARG1, (int) ARG2);
 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
-  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
-  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)	\
-  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
 			    ARG6)					\
-  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6);
 #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
 			    ARG6, ARG7)					\
-  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6, (int) ARG7);
 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
-  def_fn_type (ENUM, RETURN, 1, 0);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 0);
 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
-  def_fn_type (ENUM, RETURN, 1, 1, ARG1);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 1, (int) ARG1);
 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
-  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 2, (int) ARG1, (int) ARG2);
 #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
-  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 3, (int) ARG1, (int) ARG2, (int) ARG3);
 #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
-  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
 #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
-  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
 #define DEF_POINTER_TYPE(ENUM, TYPE) \
   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
 
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 752806e..b33630a 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -4399,47 +4399,6 @@ typedef enum c_builtin_type builtin_type;
    communication with def_fn_type.  */
 static tree builtin_types[(int) BT_LAST + 1];
 
-/* A helper function for c_common_nodes_and_builtins.  Build function type
-   for DEF with return type RET and N arguments.  If VAR is true, then the
-   function should be variadic after those N arguments.
-
-   Takes special care not to ICE if any of the types involved are
-   error_mark_node, which indicates that said type is not in fact available
-   (see builtin_type_for_size).  In which case the function type as a whole
-   should be error_mark_node.  */
-
-static void
-def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
-{
-  tree args = NULL, t;
-  va_list list;
-  int i;
-
-  va_start (list, n);
-  for (i = 0; i < n; ++i)
-    {
-      builtin_type a = (builtin_type) va_arg (list, int);
-      t = builtin_types[a];
-      if (t == error_mark_node)
-	goto egress;
-      args = tree_cons (NULL_TREE, t, args);
-    }
-  va_end (list);
-
-  args = nreverse (args);
-  if (!var)
-    args = chainon (args, void_list_node);
-
-  t = builtin_types[ret];
-  if (t == error_mark_node)
-    goto egress;
-  t = build_function_type (t, args);
-
- egress:
-  builtin_types[def] = t;
-  va_end (list);
-}
-
 /* Build builtin functions common to both C and C++ language
    frontends.  */
 
@@ -4449,35 +4408,35 @@ c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node)
 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
   builtin_types[ENUM] = VALUE;
 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
-  def_fn_type (ENUM, RETURN, 0, 0);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 0);
 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
-  def_fn_type (ENUM, RETURN, 0, 1, ARG1);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 1, (int) ARG1);
 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
-  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 2, (int) ARG1, (int) ARG2);
 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
-  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
-  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)	\
-  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
 			    ARG6)					\
-  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6);
 #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
 			    ARG6, ARG7)					\
-  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6, (int) ARG7);
 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
-  def_fn_type (ENUM, RETURN, 1, 0);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 0);
 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
-  def_fn_type (ENUM, RETURN, 1, 1, ARG1);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 1, (int) ARG1);
 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
-  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 2, (int) ARG1, (int) ARG2);
 #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
-  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 3, (int) ARG1, (int) ARG2, (int) ARG3);
 #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
-  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
 #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
-  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
 #define DEF_POINTER_TYPE(ENUM, TYPE) \
   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
 
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index eb38484..71a5365 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -1024,72 +1024,26 @@ gfc_init_builtin_functions (void)
 
 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
   builtin_types[(int) ENUM] = VALUE;
-#define DEF_FUNCTION_TYPE_0(ENUM, RETURN)                       \
-  builtin_types[(int) ENUM]                                     \
-    = build_function_type_list (builtin_types[(int) RETURN],	\
-                                NULL_TREE);
-#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1)				\
-  builtin_types[(int) ENUM]						\
-    = build_function_type_list (builtin_types[(int) RETURN],            \
-                                builtin_types[(int) ARG1],              \
-                                NULL_TREE);
-#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2)           \
-  builtin_types[(int) ENUM]                                     \
-    = build_function_type_list (builtin_types[(int) RETURN],    \
-                                builtin_types[(int) ARG1],      \
-                                builtin_types[(int) ARG2],      \
-                                NULL_TREE);
-#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3)             \
-  builtin_types[(int) ENUM]                                             \
-    = build_function_type_list (builtin_types[(int) RETURN],            \
-                                builtin_types[(int) ARG1],              \
-                                builtin_types[(int) ARG2],              \
-                                builtin_types[(int) ARG3],              \
-                                NULL_TREE);
-#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4)	\
-  builtin_types[(int) ENUM]						\
-    = build_function_type_list (builtin_types[(int) RETURN],            \
-                                builtin_types[(int) ARG1],              \
-                                builtin_types[(int) ARG2],              \
-                                builtin_types[(int) ARG3],		\
-                                builtin_types[(int) ARG4],              \
-                                NULL_TREE);
+#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 0);
+#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 1, (int) ARG1);
+#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 2, (int) ARG1, (int) ARG2);
+#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
+#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)	\
-  builtin_types[(int) ENUM]						\
-    = build_function_type_list (builtin_types[(int) RETURN],            \
-                                builtin_types[(int) ARG1],              \
-                                builtin_types[(int) ARG2],              \
-                                builtin_types[(int) ARG3],		\
-                                builtin_types[(int) ARG4],              \
-                                builtin_types[(int) ARG5],              \
-                                NULL_TREE);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
 			    ARG6)					\
-  builtin_types[(int) ENUM]						\
-    = build_function_type_list (builtin_types[(int) RETURN],            \
-                                builtin_types[(int) ARG1],              \
-                                builtin_types[(int) ARG2],              \
-                                builtin_types[(int) ARG3],		\
-                                builtin_types[(int) ARG4],		\
-                                builtin_types[(int) ARG5],              \
-                                builtin_types[(int) ARG6],              \
-                                NULL_TREE);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6);
 #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
 			    ARG6, ARG7)					\
-  builtin_types[(int) ENUM]						\
-    = build_function_type_list (builtin_types[(int) RETURN],            \
-                                builtin_types[(int) ARG1],              \
-                                builtin_types[(int) ARG2],              \
-                                builtin_types[(int) ARG3],		\
-                                builtin_types[(int) ARG4],		\
-                                builtin_types[(int) ARG5],              \
-                                builtin_types[(int) ARG6],              \
-                                builtin_types[(int) ARG7],              \
-                                NULL_TREE);
-#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN)				\
-  builtin_types[(int) ENUM]						\
-    = build_varargs_function_type_list (builtin_types[(int) RETURN],    \
-                                        NULL_TREE);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6, (int) ARG7);
+#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 0);
 #define DEF_POINTER_TYPE(ENUM, TYPE)			\
   builtin_types[(int) ENUM]				\
     = build_pointer_type (builtin_types[(int) TYPE]);
diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
index c65d916..de2eb19 100644
--- a/gcc/lto/lto-lang.c
+++ b/gcc/lto/lto-lang.c
@@ -428,40 +428,6 @@ handle_format_arg_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
 }
 
 
-/* Cribbed from c-common.c.  */
-
-static void
-def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
-{
-  tree args = NULL, t;
-  va_list list;
-  int i;
-
-  va_start (list, n);
-  for (i = 0; i < n; ++i)
-    {
-      builtin_type a = (builtin_type) va_arg (list, int);
-      t = builtin_types[a];
-      if (t == error_mark_node)
-	goto egress;
-      args = tree_cons (NULL_TREE, t, args);
-    }
-  va_end (list);
-
-  args = nreverse (args);
-  if (!var)
-    args = chainon (args, void_list_node);
-
-  t = builtin_types[ret];
-  if (t == error_mark_node)
-    goto egress;
-  t = build_function_type (t, args);
-
- egress:
-  builtin_types[def] = t;
-  va_end (list);
-}
-
 /* Used to help initialize the builtin-types.def table.  When a type of
    the correct size doesn't exist, use error_mark_node instead of NULL.
    The later results in segfaults even when a decl using the type doesn't
@@ -539,35 +505,35 @@ lto_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
   builtin_types[ENUM] = VALUE;
 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
-  def_fn_type (ENUM, RETURN, 0, 0);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 0);
 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
-  def_fn_type (ENUM, RETURN, 0, 1, ARG1);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 1, (int) ARG1);
 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
-  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 2, (int) ARG1, (int) ARG2);
 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
-  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
-  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)	\
-  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
 			    ARG6)					\
-  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6);
 #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
 			    ARG6, ARG7)					\
-  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6, (int) ARG7);
 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
-  def_fn_type (ENUM, RETURN, 1, 0);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 0);
 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
-  def_fn_type (ENUM, RETURN, 1, 1, ARG1);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 1, (int) ARG1);
 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
-  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 2, (int) ARG1, (int) ARG2);
 #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
-  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 3, (int) ARG1, (int) ARG2, (int) ARG3);
 #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
-  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
 #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
-  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
+  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
 #define DEF_POINTER_TYPE(ENUM, TYPE) \
   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
 
diff --git a/gcc/tree.c b/gcc/tree.c
index d0c18b1..008e6f7 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -7631,6 +7631,79 @@ build_varargs_function_type_list (tree return_type, ...)
   return args;
 }
 
+/* Build a function type.  RETURN_TYPE is the type returned by the
+   function; VAARGS indicates whether the function takes varargs.  The
+   function takes N named arguments, the types of which are provided in
+   ARG_TYPES.  */
+
+static tree
+build_function_type_array_1 (bool vaargs, tree return_type, int n,
+			     tree *arg_types)
+{
+  int i;
+  tree t = vaargs ? NULL_TREE : void_list_node;
+
+  for (i = n - 1; i >= 0; i--)
+    t = tree_cons (NULL_TREE, arg_types[i], t);
+
+  return build_function_type (return_type, t);
+}
+
+/* Build a function type.  RETURN_TYPE is the type returned by the
+   function.  The function takes N named arguments, the types of which
+   are provided in ARG_TYPES.  */
+
+tree
+build_function_type_array (tree return_type, int n, tree *arg_types)
+{
+  return build_function_type_array_1 (false, return_type, n, arg_types);
+}
+
+/* Build a variable argument function type.  RETURN_TYPE is the type
+   returned by the function.  The function takes N named arguments, the
+   types of which are provided in ARG_TYPES.  */
+
+tree
+build_varargs_function_type_array (tree return_type, int n, tree *arg_types)
+{
+  return build_function_type_array_1 (true, return_type, n, arg_types);
+}
+
+/* Build a function type and store it in BUILTIN_TYPES at FNTYPE_IDX.
+   RETURN_TYPE_IDX is the index of the return type of the function in
+   BUILTIN_TYPES.  VAARGS indicates whether the function takes varargs.
+   The function takes N named arguments, of which indices into
+   BUILTIN_TYPES are provided as varargs.  */
+
+void
+define_builtin_function_type (tree *builtin_types, int fntype_idx,
+			      int return_type_idx, bool vaargs,
+			      int n, ...)
+{
+  int i;
+  va_list list;
+  tree t, *arg_types = XALLOCAVEC (tree, n);
+
+  va_start (list, n);
+  for (i = 0; i < n; i++)
+    {
+      int arg_type_idx = va_arg (list, int);
+      t = builtin_types[arg_type_idx];
+      if (t == error_mark_node)
+	goto egress;
+      arg_types[i] = t;
+    }
+
+  t = builtin_types[return_type_idx];
+  if (t == error_mark_node)
+    goto egress;
+  t = build_function_type_array_1 (vaargs, t, n, arg_types);
+
+ egress:
+  builtin_types[fntype_idx] = t;
+  va_end (list);
+}
+
 /* Build a METHOD_TYPE for a member of BASETYPE.  The RETTYPE (a TYPE)
    and ARGTYPES (a TREE_LIST) are the return type and arguments types
    for the method.  An implicit additional parameter (of type
diff --git a/gcc/tree.h b/gcc/tree.h
index 0bc98cd..0e231e9 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4252,6 +4252,9 @@ extern tree build_function_type_list (tree, ...);
 extern tree build_function_type_skip_args (tree, bitmap);
 extern tree build_function_decl_skip_args (tree, bitmap);
 extern tree build_varargs_function_type_list (tree, ...);
+extern tree build_function_type_array (tree, int, tree *);
+extern tree build_varargs_function_type_array (tree, int, tree *);
+extern void define_builtin_function_type (tree *, int, int, bool, int, ...);
 extern tree build_method_type_directly (tree, tree, tree);
 extern tree build_method_type (tree, tree);
 extern tree build_offset_type (tree, tree);

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

* Re: [PATCH] centralize builtin function type building
  2011-04-21 15:37 [PATCH] centralize builtin function type building Nathan Froyd
@ 2011-04-21 15:54 ` Richard Guenther
  2011-04-21 19:32   ` Michael Meissner
  2011-04-22 16:59   ` Nathan Froyd
  2011-04-22 19:28 ` Michael Meissner
  1 sibling, 2 replies; 6+ messages in thread
From: Richard Guenther @ 2011-04-21 15:54 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: gcc-patches

On Thu, Apr 21, 2011 at 5:04 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> This patch does two things:
>
> - centralizes some infrastructure for defining builtin function types
>  for frontends by providing a common function that
>  DEF_FUNCTION_TYPE_FOO macros can call; and
>
> - in order to do that well, it also introduces
>  build{,_varargs}_function_type_array for cases when
>  build_function_type_list's interface doesn't work so well.
>
> build_function_type_list could have been used instead, but it would lose
> the error_mark_node handling provided in the C/C++/Ada/LTO frontends.
> This new interface will be necessary for eliminating other uses of
> build_function_type anyway.
>
> It would have been easier to move all of the builtin-types stuff into
> the middle-end, but Fortran doesn't use builtin-types.def.  Even if it
> did, I suppose it's possible that some new front-end could have its own
> set of builtin types, so I'm leaving things as they are.

But this is what should be done, at least for all builtins in the
BUILT_IN_NORMAL category.  ISTR Fortran was once running into
the issue of assigning different DECL_FUNCTION_CODE numbers to
those builtins than other languages, breaking LTO.

So, it would be indeed nice to have a central middle-end place to
instantiate those builtins and their required types.  I'm not sure how
far we are from that and am too lazy to look right now ...

Richard.

> The new functions can eliminate some of the games that were played with
> the recent backend changes to use build_function_type_list; if this
> patch is approved, I'll make the (currently uncommitted) patches that
> could use build_function_type_array do so.
>
> Bootstrap and testing in progress on x86_64-unknown-linux-gnu.  OK to
> commit if successful?
>
> -Nathan
>
> gcc/ada/
>        * gcc-interface/utils.c (def_fn_type): Delete.
>        (DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
>        define_builtin_function_type.
>        (DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
>        (DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
>        (DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
>        (DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
>        (DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.
>
> gcc/c-family/:
>        * c-common.c (def_fn_type): Delete.
>        (DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
>        define_builtin_function_type.
>        (DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
>        (DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
>        (DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
>        (DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
>        (DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.
>
> gcc/
>        * tree.h (build_function_type_array): Declare.
>        (build_varargs_function_type_array, define_builtin_function_type):
>        Declare.
>        * tree.c (build_function_type_array_1): Define.
>        (build_function_type_array, build_varargs_function_type_array): Define.
>        (define_builtin_function_type): Define.
>
> gcc/fortran/
>        * f95-lang.c (DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change
>        to use define_builtin_function_type.
>        (DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
>        (DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
>        (DEF_FUNCTION_TYPE_VAR_0): Likewise.
>
> gcc/lto/
>        * lto-lang.c (def_fn_type): Delete.
>        (DEF_FUNCTION_TYPE_0, DEF_FUNCTION_TYPE_1): Change to use
>        define_builtin_function_type.
>        (DEF_FUNCTION_TYPE_2, DEF_FUNCTION_TYPE_3, DEF_FUNCTION_TYPE_4):
>        (DEF_FUNCTION_TYPE_5, DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7):
>        (DEF_FUNCTION_TYPE_VAR_0, DEF_FUNCTION_TYPE_VAR_1):
>        (DEF_FUNCTION_TYPE_VAR_2, DEF_FUNCTION_TYPE_VAR_3):
>        (DEF_FUNCTION_TYPE_VAR_4, DEF_FUNCTION_TYPE_VAR_5): Likewise.
>
> diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
> index 1031ee9..6eb136d 100644
> --- a/gcc/ada/gcc-interface/utils.c
> +++ b/gcc/ada/gcc-interface/utils.c
> @@ -4952,47 +4952,6 @@ typedef enum c_builtin_type builtin_type;
>  /* A temporary array used in communication with def_fn_type.  */
>  static GTY(()) tree builtin_types[(int) BT_LAST + 1];
>
> -/* A helper function for install_builtin_types.  Build function type
> -   for DEF with return type RET and N arguments.  If VAR is true, then the
> -   function should be variadic after those N arguments.
> -
> -   Takes special care not to ICE if any of the types involved are
> -   error_mark_node, which indicates that said type is not in fact available
> -   (see builtin_type_for_size).  In which case the function type as a whole
> -   should be error_mark_node.  */
> -
> -static void
> -def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
> -{
> -  tree args = NULL, t;
> -  va_list list;
> -  int i;
> -
> -  va_start (list, n);
> -  for (i = 0; i < n; ++i)
> -    {
> -      builtin_type a = (builtin_type) va_arg (list, int);
> -      t = builtin_types[a];
> -      if (t == error_mark_node)
> -       goto egress;
> -      args = tree_cons (NULL_TREE, t, args);
> -    }
> -  va_end (list);
> -
> -  args = nreverse (args);
> -  if (!var)
> -    args = chainon (args, void_list_node);
> -
> -  t = builtin_types[ret];
> -  if (t == error_mark_node)
> -    goto egress;
> -  t = build_function_type (t, args);
> -
> - egress:
> -  builtin_types[def] = t;
> -  va_end (list);
> -}
> -
>  /* Build the builtin function types and install them in the builtin_types
>    array for later use in builtin function decls.  */
>
> @@ -5016,35 +4975,35 @@ install_builtin_function_types (void)
>  #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
>   builtin_types[ENUM] = VALUE;
>  #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 0, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 0);
>  #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 0, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)        \
> -  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6)                                       \
> -  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6);
>  #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6, ARG7)                                 \
> -  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6, (int) ARG7);
>  #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 1, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 0);
>  #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 1, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
> -  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_POINTER_TYPE(ENUM, TYPE) \
>   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
>
> diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
> index 752806e..b33630a 100644
> --- a/gcc/c-family/c-common.c
> +++ b/gcc/c-family/c-common.c
> @@ -4399,47 +4399,6 @@ typedef enum c_builtin_type builtin_type;
>    communication with def_fn_type.  */
>  static tree builtin_types[(int) BT_LAST + 1];
>
> -/* A helper function for c_common_nodes_and_builtins.  Build function type
> -   for DEF with return type RET and N arguments.  If VAR is true, then the
> -   function should be variadic after those N arguments.
> -
> -   Takes special care not to ICE if any of the types involved are
> -   error_mark_node, which indicates that said type is not in fact available
> -   (see builtin_type_for_size).  In which case the function type as a whole
> -   should be error_mark_node.  */
> -
> -static void
> -def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
> -{
> -  tree args = NULL, t;
> -  va_list list;
> -  int i;
> -
> -  va_start (list, n);
> -  for (i = 0; i < n; ++i)
> -    {
> -      builtin_type a = (builtin_type) va_arg (list, int);
> -      t = builtin_types[a];
> -      if (t == error_mark_node)
> -       goto egress;
> -      args = tree_cons (NULL_TREE, t, args);
> -    }
> -  va_end (list);
> -
> -  args = nreverse (args);
> -  if (!var)
> -    args = chainon (args, void_list_node);
> -
> -  t = builtin_types[ret];
> -  if (t == error_mark_node)
> -    goto egress;
> -  t = build_function_type (t, args);
> -
> - egress:
> -  builtin_types[def] = t;
> -  va_end (list);
> -}
> -
>  /* Build builtin functions common to both C and C++ language
>    frontends.  */
>
> @@ -4449,35 +4408,35 @@ c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node)
>  #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
>   builtin_types[ENUM] = VALUE;
>  #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 0, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 0);
>  #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 0, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)        \
> -  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6)                                       \
> -  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6);
>  #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6, ARG7)                                 \
> -  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6, (int) ARG7);
>  #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 1, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 0);
>  #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 1, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
> -  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_POINTER_TYPE(ENUM, TYPE) \
>   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
>
> diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
> index eb38484..71a5365 100644
> --- a/gcc/fortran/f95-lang.c
> +++ b/gcc/fortran/f95-lang.c
> @@ -1024,72 +1024,26 @@ gfc_init_builtin_functions (void)
>
>  #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
>   builtin_types[(int) ENUM] = VALUE;
> -#define DEF_FUNCTION_TYPE_0(ENUM, RETURN)                       \
> -  builtin_types[(int) ENUM]                                     \
> -    = build_function_type_list (builtin_types[(int) RETURN],   \
> -                                NULL_TREE);
> -#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1)                                \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                NULL_TREE);
> -#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2)           \
> -  builtin_types[(int) ENUM]                                     \
> -    = build_function_type_list (builtin_types[(int) RETURN],    \
> -                                builtin_types[(int) ARG1],      \
> -                                builtin_types[(int) ARG2],      \
> -                                NULL_TREE);
> -#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3)             \
> -  builtin_types[(int) ENUM]                                             \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                builtin_types[(int) ARG2],              \
> -                                builtin_types[(int) ARG3],              \
> -                                NULL_TREE);
> -#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4)      \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                builtin_types[(int) ARG2],              \
> -                                builtin_types[(int) ARG3],             \
> -                                builtin_types[(int) ARG4],              \
> -                                NULL_TREE);
> +#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 0);
> +#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 1, (int) ARG1);
> +#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 2, (int) ARG1, (int) ARG2);
> +#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
> +#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)        \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                builtin_types[(int) ARG2],              \
> -                                builtin_types[(int) ARG3],             \
> -                                builtin_types[(int) ARG4],              \
> -                                builtin_types[(int) ARG5],              \
> -                                NULL_TREE);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6)                                       \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                builtin_types[(int) ARG2],              \
> -                                builtin_types[(int) ARG3],             \
> -                                builtin_types[(int) ARG4],             \
> -                                builtin_types[(int) ARG5],              \
> -                                builtin_types[(int) ARG6],              \
> -                                NULL_TREE);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6);
>  #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6, ARG7)                                 \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_function_type_list (builtin_types[(int) RETURN],            \
> -                                builtin_types[(int) ARG1],              \
> -                                builtin_types[(int) ARG2],              \
> -                                builtin_types[(int) ARG3],             \
> -                                builtin_types[(int) ARG4],             \
> -                                builtin_types[(int) ARG5],              \
> -                                builtin_types[(int) ARG6],              \
> -                                builtin_types[(int) ARG7],              \
> -                                NULL_TREE);
> -#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN)                          \
> -  builtin_types[(int) ENUM]                                            \
> -    = build_varargs_function_type_list (builtin_types[(int) RETURN],    \
> -                                        NULL_TREE);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6, (int) ARG7);
> +#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 0);
>  #define DEF_POINTER_TYPE(ENUM, TYPE)                   \
>   builtin_types[(int) ENUM]                            \
>     = build_pointer_type (builtin_types[(int) TYPE]);
> diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c
> index c65d916..de2eb19 100644
> --- a/gcc/lto/lto-lang.c
> +++ b/gcc/lto/lto-lang.c
> @@ -428,40 +428,6 @@ handle_format_arg_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name),
>  }
>
>
> -/* Cribbed from c-common.c.  */
> -
> -static void
> -def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
> -{
> -  tree args = NULL, t;
> -  va_list list;
> -  int i;
> -
> -  va_start (list, n);
> -  for (i = 0; i < n; ++i)
> -    {
> -      builtin_type a = (builtin_type) va_arg (list, int);
> -      t = builtin_types[a];
> -      if (t == error_mark_node)
> -       goto egress;
> -      args = tree_cons (NULL_TREE, t, args);
> -    }
> -  va_end (list);
> -
> -  args = nreverse (args);
> -  if (!var)
> -    args = chainon (args, void_list_node);
> -
> -  t = builtin_types[ret];
> -  if (t == error_mark_node)
> -    goto egress;
> -  t = build_function_type (t, args);
> -
> - egress:
> -  builtin_types[def] = t;
> -  va_end (list);
> -}
> -
>  /* Used to help initialize the builtin-types.def table.  When a type of
>    the correct size doesn't exist, use error_mark_node instead of NULL.
>    The later results in segfaults even when a decl using the type doesn't
> @@ -539,35 +505,35 @@ lto_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
>  #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
>   builtin_types[ENUM] = VALUE;
>  #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 0, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 0);
>  #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 0, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)        \
> -  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6)                                       \
> -  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 6, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6);
>  #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
>                            ARG6, ARG7)                                 \
> -  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, false, 7, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5, (int) ARG6, (int) ARG7);
>  #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
> -  def_fn_type (ENUM, RETURN, 1, 0);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 0);
>  #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
> -  def_fn_type (ENUM, RETURN, 1, 1, ARG1);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 1, (int) ARG1);
>  #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
> -  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 2, (int) ARG1, (int) ARG2);
>  #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
> -  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 3, (int) ARG1, (int) ARG2, (int) ARG3);
>  #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
> -  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 4, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4);
>  #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
> -  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
> +  define_builtin_function_type (builtin_types, (int) ENUM, (int) RETURN, true, 5, (int) ARG1, (int) ARG2, (int) ARG3, (int) ARG4, (int) ARG5);
>  #define DEF_POINTER_TYPE(ENUM, TYPE) \
>   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
>
> diff --git a/gcc/tree.c b/gcc/tree.c
> index d0c18b1..008e6f7 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -7631,6 +7631,79 @@ build_varargs_function_type_list (tree return_type, ...)
>   return args;
>  }
>
> +/* Build a function type.  RETURN_TYPE is the type returned by the
> +   function; VAARGS indicates whether the function takes varargs.  The
> +   function takes N named arguments, the types of which are provided in
> +   ARG_TYPES.  */
> +
> +static tree
> +build_function_type_array_1 (bool vaargs, tree return_type, int n,
> +                            tree *arg_types)
> +{
> +  int i;
> +  tree t = vaargs ? NULL_TREE : void_list_node;
> +
> +  for (i = n - 1; i >= 0; i--)
> +    t = tree_cons (NULL_TREE, arg_types[i], t);
> +
> +  return build_function_type (return_type, t);
> +}
> +
> +/* Build a function type.  RETURN_TYPE is the type returned by the
> +   function.  The function takes N named arguments, the types of which
> +   are provided in ARG_TYPES.  */
> +
> +tree
> +build_function_type_array (tree return_type, int n, tree *arg_types)
> +{
> +  return build_function_type_array_1 (false, return_type, n, arg_types);
> +}
> +
> +/* Build a variable argument function type.  RETURN_TYPE is the type
> +   returned by the function.  The function takes N named arguments, the
> +   types of which are provided in ARG_TYPES.  */
> +
> +tree
> +build_varargs_function_type_array (tree return_type, int n, tree *arg_types)
> +{
> +  return build_function_type_array_1 (true, return_type, n, arg_types);
> +}
> +
> +/* Build a function type and store it in BUILTIN_TYPES at FNTYPE_IDX.
> +   RETURN_TYPE_IDX is the index of the return type of the function in
> +   BUILTIN_TYPES.  VAARGS indicates whether the function takes varargs.
> +   The function takes N named arguments, of which indices into
> +   BUILTIN_TYPES are provided as varargs.  */
> +
> +void
> +define_builtin_function_type (tree *builtin_types, int fntype_idx,
> +                             int return_type_idx, bool vaargs,
> +                             int n, ...)
> +{
> +  int i;
> +  va_list list;
> +  tree t, *arg_types = XALLOCAVEC (tree, n);
> +
> +  va_start (list, n);
> +  for (i = 0; i < n; i++)
> +    {
> +      int arg_type_idx = va_arg (list, int);
> +      t = builtin_types[arg_type_idx];
> +      if (t == error_mark_node)
> +       goto egress;
> +      arg_types[i] = t;
> +    }
> +
> +  t = builtin_types[return_type_idx];
> +  if (t == error_mark_node)
> +    goto egress;
> +  t = build_function_type_array_1 (vaargs, t, n, arg_types);
> +
> + egress:
> +  builtin_types[fntype_idx] = t;
> +  va_end (list);
> +}
> +
>  /* Build a METHOD_TYPE for a member of BASETYPE.  The RETTYPE (a TYPE)
>    and ARGTYPES (a TREE_LIST) are the return type and arguments types
>    for the method.  An implicit additional parameter (of type
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 0bc98cd..0e231e9 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -4252,6 +4252,9 @@ extern tree build_function_type_list (tree, ...);
>  extern tree build_function_type_skip_args (tree, bitmap);
>  extern tree build_function_decl_skip_args (tree, bitmap);
>  extern tree build_varargs_function_type_list (tree, ...);
> +extern tree build_function_type_array (tree, int, tree *);
> +extern tree build_varargs_function_type_array (tree, int, tree *);
> +extern void define_builtin_function_type (tree *, int, int, bool, int, ...);
>  extern tree build_method_type_directly (tree, tree, tree);
>  extern tree build_method_type (tree, tree);
>  extern tree build_offset_type (tree, tree);
>

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

* Re: [PATCH] centralize builtin function type building
  2011-04-21 15:54 ` Richard Guenther
@ 2011-04-21 19:32   ` Michael Meissner
  2011-04-22 16:59   ` Nathan Froyd
  1 sibling, 0 replies; 6+ messages in thread
From: Michael Meissner @ 2011-04-21 19:32 UTC (permalink / raw)
  To: Richard Guenther, zadeck; +Cc: Nathan Froyd, gcc-patches

On Thu, Apr 21, 2011 at 05:36:42PM +0200, Richard Guenther wrote:
> On Thu, Apr 21, 2011 at 5:04 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> > This patch does two things:
> >
> > - centralizes some infrastructure for defining builtin function types
> >  for frontends by providing a common function that
> >  DEF_FUNCTION_TYPE_FOO macros can call; and
> >
> > - in order to do that well, it also introduces
> >  build{,_varargs}_function_type_array for cases when
> >  build_function_type_list's interface doesn't work so well.
> >
> > build_function_type_list could have been used instead, but it would lose
> > the error_mark_node handling provided in the C/C++/Ada/LTO frontends.
> > This new interface will be necessary for eliminating other uses of
> > build_function_type anyway.
> >
> > It would have been easier to move all of the builtin-types stuff into
> > the middle-end, but Fortran doesn't use builtin-types.def.  Even if it
> > did, I suppose it's possible that some new front-end could have its own
> > set of builtin types, so I'm leaving things as they are.
> 
> But this is what should be done, at least for all builtins in the
> BUILT_IN_NORMAL category.  ISTR Fortran was once running into
> the issue of assigning different DECL_FUNCTION_CODE numbers to
> those builtins than other languages, breaking LTO.
> 
> So, it would be indeed nice to have a central middle-end place to
> instantiate those builtins and their required types.  I'm not sure how
> far we are from that and am too lazy to look right now ...

I agree that it is desirable that the backend builtin index not overlap with
the standard builtin index (and front end builtin index).  I was starting to
look at this, when I learned Kenneth Zadeck was working on a more comprehensive
solution for backend builtin types.  Obviously all 3 of our efforts should be
merged into one goal.

-- 
Michael Meissner, IBM
5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA
meissner@linux.vnet.ibm.com	fax +1 (978) 399-6899

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

* Re: [PATCH] centralize builtin function type building
  2011-04-21 15:54 ` Richard Guenther
  2011-04-21 19:32   ` Michael Meissner
@ 2011-04-22 16:59   ` Nathan Froyd
  1 sibling, 0 replies; 6+ messages in thread
From: Nathan Froyd @ 2011-04-22 16:59 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches, fortran

On Thu, Apr 21, 2011 at 05:36:42PM +0200, Richard Guenther wrote:
> On Thu, Apr 21, 2011 at 5:04 PM, Nathan Froyd <froydnj@codesourcery.com> wrote:
> > This patch does two things:
> >
> > - centralizes some infrastructure for defining builtin function types
> >  for frontends by providing a common function that
> >  DEF_FUNCTION_TYPE_FOO macros can call; and
> >
> > - in order to do that well, it also introduces
> >  build{,_varargs}_function_type_array for cases when
> >  build_function_type_list's interface doesn't work so well.
> >
> > It would have been easier to move all of the builtin-types stuff into
> > the middle-end, but Fortran doesn't use builtin-types.def.  Even if it
> > did, I suppose it's possible that some new front-end could have its own
> > set of builtin types, so I'm leaving things as they are.
> 
> But this is what should be done, at least for all builtins in the
> BUILT_IN_NORMAL category.  ISTR Fortran was once running into
> the issue of assigning different DECL_FUNCTION_CODE numbers to
> those builtins than other languages, breaking LTO.
> 
> So, it would be indeed nice to have a central middle-end place to
> instantiate those builtins and their required types.  I'm not sure how
> far we are from that and am too lazy to look right now ...

I agree that it would be better to have a central middle-end place for
this; I'm not entirely sure why Fortran opts to use a separate set of
types; AFAICS, it's a strict subset.  Fortran folks...?

The question of decls is something different and unrelated to this
patch, IMHO.  Is the patch OK as-is, or should I work on merging the
types into the middle-end in addition?

-Nathan

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

* Re: [PATCH] centralize builtin function type building
  2011-04-21 15:37 [PATCH] centralize builtin function type building Nathan Froyd
  2011-04-21 15:54 ` Richard Guenther
@ 2011-04-22 19:28 ` Michael Meissner
  2011-04-22 19:46   ` Nathan Froyd
  1 sibling, 1 reply; 6+ messages in thread
From: Michael Meissner @ 2011-04-22 19:28 UTC (permalink / raw)
  To: Nathan Froyd, Kenneth Zadeck; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2464 bytes --]

On Thu, Apr 21, 2011 at 11:04:47AM -0400, Nathan Froyd wrote:
> This patch does two things:
> 
> - centralizes some infrastructure for defining builtin function types
>   for frontends by providing a common function that
>   DEF_FUNCTION_TYPE_FOO macros can call; and
> 
> - in order to do that well, it also introduces
>   build{,_varargs}_function_type_array for cases when
>   build_function_type_list's interface doesn't work so well.
> 
> build_function_type_list could have been used instead, but it would lose
> the error_mark_node handling provided in the C/C++/Ada/LTO frontends.
> This new interface will be necessary for eliminating other uses of
> build_function_type anyway.
> 
> It would have been easier to move all of the builtin-types stuff into
> the middle-end, but Fortran doesn't use builtin-types.def.  Even if it
> did, I suppose it's possible that some new front-end could have its own
> set of builtin types, so I'm leaving things as they are.
> 
> The new functions can eliminate some of the games that were played with
> the recent backend changes to use build_function_type_list; if this
> patch is approved, I'll make the (currently uncommitted) patches that
> could use build_function_type_array do so.
> 
> Bootstrap and testing in progress on x86_64-unknown-linux-gnu.  OK to
> commit if successful?

Now that I've looked at the patch, a couple of things jump out:

1) For the DEF_FUNCTION_* replacements, the lines exceed the normal 79
   character limits we use as coding guidelines.

2) I'm not a fan of having a varargs function with an explicit count.  I tend
   to prefer a marker element (like NULL_TREE) as the last element.  In this
   case, since it is being used in macros that do have fixed elements, it isn't
   a problem.

3) I'm also not a fan of passing the index into the type array, instead of a
   tree value to the call.  If you pass a tree, then it allows MD builtins to
   call it before we switch to having the MD and front end builtins share the
   bultin index.

I'm enclosing the beginnings of the patch that I was working on to allow the MD
to specify *.def files to be included in the master builtin list.  Obviously we
need to tie in the front end builtins into the scheme.  I've been waiting to
see what Kenny Z was doing in his patches before continuing out.

-- 
Michael Meissner, IBM
5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA
meissner@linux.vnet.ibm.com	fax +1 (978) 399-6899

[-- Attachment #2: gcc-power7.patch235 --]
[-- Type: text/plain, Size: 15222 bytes --]

[gcc]
2011-04-05  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* tree.h (enum built_in_function): Add support for machine
	dependent builtins to be generated along with normal builtins.
	Create new include files that include the standard .def files as
	well as any optional machine dependent files.
	* builtins.c (built_in_names): Ditto.
	* configure.ac (extra_builtin_attrs): Ditto.
	(extra_builtin_types): Ditto.
	(extra_builtin_md): Ditto.
	* config.gcc (extra_builtin_attrs): Ditto.
	(extra_builtin_types): Ditto.
	(extra_builtin_md): Ditto.
	* Makefile.in (builtin-types.h): Ditto.
	(builtin-attrs.h): Ditto.
	(builtin-md.h): Ditto.
	(BUILTIN_MD_H): Rename from BUILTINS_DEF, and add machine
	dependent includes.  Change all uses.
	(BUILTIN_ATTRS_H): New variable for builtin attribute include
	files.
	(BUILTIN_TYPES_H): New variable for builtin types include files.

	* configure: Regenerate.

[gcc/c-family]
2011-04-05  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* c-common.c (enum built_in_attribute): Add support for MD
	builtins to be generated along with normal builtins.
	(enum c_builtin_type): Ditto.
	(c_define_builtins): Ditto.
	(c_init_attributes): Ditto.

[gcc/lto]
2011-04-05  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* lto-lang.c (enum built_in_attribute): Add support for machine
	dependent builtins to be generated along with normal builtins.
	(enum lto_builtin_type): Ditto.
	(def_fn_type): Ditto.
	(lto_init_attributes): Ditto.
	(lto_define_builtins): Ditto.
	(lto_register_builtin_type): Ditto.
	* Make-lang.in (lto/lto-lang.o): Ditto.

Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 171948)
+++ gcc/tree.h	(working copy)
@@ -1,6 +1,6 @@
 /* Front-end tree definitions for GNU compiler.
    Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -226,7 +226,7 @@ extern const char *const built_in_class_
 #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) ENUM,
 enum built_in_function
 {
-#include "builtins.def"
+#include "builtin-md.h"
 
   /* Complex division routines in libgcc.  These are done via builtins
      because emit_library_call_value can't handle complex values.  */
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c	(revision 171947)
+++ gcc/builtins.c	(working copy)
@@ -69,7 +69,7 @@ const char *const built_in_class_names[4
 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
 const char * built_in_names[(int) END_BUILTINS] =
 {
-#include "builtins.def"
+#include "builtins_md.h"
 };
 #undef DEF_BUILTIN
 
Index: gcc/configure.ac
===================================================================
--- gcc/configure.ac	(revision 171947)
+++ gcc/configure.ac	(working copy)
@@ -4786,6 +4786,9 @@ AC_SUBST(c_target_objs)
 AC_SUBST(cxx_target_objs)
 AC_SUBST(fortran_target_objs)
 AC_SUBST(target_cpu_default)
+AC_SUBST(extra_builtin_attrs)
+AC_SUBST(extra_builtin_types)
+AC_SUBST(extra_builtin_md)
 
 AC_SUBST_FILE(language_hooks)
 
Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	(revision 171947)
+++ gcc/config.gcc	(working copy)
@@ -111,6 +111,12 @@
 #  extra_headers	List of used header files from the directory
 #			config/${cpu_type}.
 #
+#  extra_builtin_attrs	List of extra builtin attributes include files.
+#
+#  extra_builtin_types	List of extra builtin types include files.
+#
+#  extra_builtin_md	List of extra machine dependent builtin include files.
+#
 #  user_headers_inc_next_pre
 #			List of header file names of internal gcc header
 #			files, which should be prefixed by an include_next.
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 171947)
+++ gcc/Makefile.in	(working copy)
@@ -484,6 +484,9 @@ host_xm_defines=@host_xm_defines@
 xm_file_list=@xm_file_list@
 xm_include_list=@xm_include_list@
 xm_defines=@xm_defines@
+extra_builtin_attrs=@extra_builtin_attrs@
+extra_builtin_types=@extra_builtin_types@
+extra_builtin_md=@extra_builtin_md@
 lang_checks=check-gcc
 lang_checks_parallelized=check-gcc
 # This lists a couple of test files that take most time during check-gcc.
@@ -887,9 +890,11 @@ RTL_H = $(RTL_BASE_H) genrtl.h vecir.h
 RTL_ERROR_H = $(RTL_H) $(DIAGNOSTIC_CORE_H)
 READ_MD_H = $(OBSTACK_H) $(HASHTAB_H) read-md.h
 PARAMS_H = params.h params.def
-BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def
+BUILTIN_MD_H = builtin-md.h builtins.def sync-builtins.def omp-builtins.def $(extra_builtin_md)
+BUILTIN_TYPES_H = builtin-types.h builtin-types.def $(extra_builtin_types)
+BUILTIN_ATTRS_H = builtin-attrs.h builtin-attrs.def $(extra_builtin_attrs)
 TREE_H = tree.h all-tree.def tree.def c-family/c-common.def \
-	$(lang_tree_files) $(MACHMODE_H) tree-check.h $(BUILTINS_DEF) \
+	$(lang_tree_files) $(MACHMODE_H) tree-check.h $(BUILTIN_MD_H) \
 	$(INPUT_H) statistics.h $(VEC_H) treestruct.def $(HASHTAB_H) \
 	double-int.h alias.h $(SYMTAB_H) $(FLAGS_H) vecir.h \
 	$(REAL_H) $(FIXED_VALUE_H)
@@ -1667,6 +1672,9 @@ bconfig.h: cs-bconfig.h ; @true
 tconfig.h: cs-tconfig.h ; @true
 tm.h: cs-tm.h ; @true
 tm_p.h: cs-tm_p.h ; @true
+builtin-types.h: cs-builtin-types.h ; @true
+builtin-attrs.h: cs-builtin-attrs.h ; @true
+builtin-md.h: cs-builtin-md.h ; @true
 
 cs-config.h: Makefile
 	TARGET_CPU_DEFAULT="" \
@@ -1693,6 +1701,27 @@ cs-tm_p.h: Makefile
 	HEADERS="$(tm_p_include_list)" DEFINES="" \
 	$(SHELL) $(srcdir)/mkconfig.sh tm_p.h
 
+cs-builtin-attrs.h: Makefile
+	for inc in builtin-attrs.def $(extra_builtin_attrs); do \
+		echo "#include \"$$inc\""; \
+	done > tmp-builtin-attrs.h \
+	&& $(srcdir)/../move-if-change tmp-builtin-attrs.h builtin-attrs.h
+	touch cs-builtins-attrs.h
+
+cs-builtin-md.h: Makefile
+	for inc in builtins.def $(extra_builtin_md); do \
+		echo "#include \"$$inc\""; \
+	done > tmp-builtin-md.h \
+	&& $(srcdir)/../move-if-change tmp-builtin-md.h builtin-md.h
+	touch cs-builtin-md.h
+
+cs-builtin-types.h: Makefile
+	for inc in builtin-types.def $(extra_builtin_types); do \
+		echo "#include \"$$inc\""; \
+	done > tmp-builtin-types.h \
+	&& $(srcdir)/../move-if-change tmp-builtin-types.h builtin-types.h
+	touch cs-builtin-types.h
+
 # Don't automatically run autoconf, since configure.ac might be accidentally
 # newer than configure.  Also, this writes into the source directory which
 # might be on a read-only file system.  If configured for maintainer mode
@@ -2090,11 +2119,11 @@ lto-wrapper.o: lto-wrapper.c $(CONFIG_H)
 c-family/c-common.o : c-family/c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
 	$(TM_H) $(TREE_H) \
 	$(OBSTACK_H) $(C_COMMON_H) $(FLAGS_H) toplev.h output.h $(C_PRAGMA_H) \
-	$(GGC_H) builtin-types.def builtin-attrs.def \
+	$(GGC_H) $(BUILTIN_TYPES_H) $(BUILTIN_ATTRS_H) \
 	$(DIAGNOSTIC_H) langhooks.h c-family/c-objc.h \
 	$(TARGET_H) tree-iterator.h langhooks.h tree-mudflap.h \
 	intl.h $(OPTS_H) $(CPPLIB_H) $(TREE_INLINE_H) $(HASHTAB_H) \
-	$(BUILTINS_DEF) $(CGRAPH_H) $(BASIC_BLOCK_H) $(TARGET_DEF_H) \
+	$(BUILTIN_MD_H) $(CGRAPH_H) $(BASIC_BLOCK_H) $(TARGET_DEF_H) \
 	$(LIBFUNCS_H) \
 	gt-c-family-c-common.h
 
@@ -2898,7 +2927,7 @@ builtins.o : builtins.c $(CONFIG_H) $(SY
    $(EXPR_H) $(OPTABS_H) insn-config.h $(RECOG_H) output.h typeclass.h \
    hard-reg-set.h $(DIAGNOSTIC_CORE_H) hard-reg-set.h $(EXCEPT_H) \
    $(TM_P_H) $(PREDICT_H) $(LIBFUNCS_H) langhooks.h $(BASIC_BLOCK_H) \
-   tree-mudflap.h realmpfr.h $(BUILTINS_DEF) $(MACHMODE_H) \
+   tree-mudflap.h realmpfr.h $(BUILTIN_MD_H) $(MACHMODE_H) \
    $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) value-prof.h
 calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(TREE_H) $(FLAGS_H) $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \
@@ -4411,6 +4440,7 @@ clean: mostlyclean lang.clean
 	-rm -f libgcc_s*
 	-rm -f libunwind*
 	-rm -f config.h tconfig.h bconfig.h tm_p.h tm.h
+	-rm -f builtin-types.h builtin-attrs.h builtin-md.h
 	-rm -f options.c options.h optionlist
 	-rm -f cs-*
 	-rm -f doc/*.dvi
Index: gcc/configure
===================================================================
--- gcc/configure	(revision 171947)
+++ gcc/configure	(working copy)
@@ -608,6 +608,9 @@ PPLINC
 PPLLIBS
 GMPINC
 GMPLIBS
+extra_builtin_md
+extra_builtin_types
+extra_builtin_attrs
 target_cpu_default
 fortran_target_objs
 cxx_target_objs
@@ -17505,7 +17508,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 17508 "configure"
+#line 17511 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -17611,7 +17614,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 17614 "configure"
+#line 17617 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -26226,6 +26229,9 @@ fi
 
 
 
+
+
+
 # Echo link setup.
 if test x${build} = x${host} ; then
   if test x${host} = x${target} ; then
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 171947)
+++ gcc/c-family/c-common.c	(working copy)
@@ -4333,7 +4333,7 @@ enum built_in_attribute
 #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
 #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
-#include "builtin-attrs.def"
+#include "builtin-attrs.h"
 #undef DEF_ATTR_NULL_TREE
 #undef DEF_ATTR_INT
 #undef DEF_ATTR_IDENT
@@ -4364,7 +4364,7 @@ enum c_builtin_type
 #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \
   NAME,
 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
-#include "builtin-types.def"
+#include "builtin-types.h"
 #undef DEF_PRIMITIVE_TYPE
 #undef DEF_FUNCTION_TYPE_0
 #undef DEF_FUNCTION_TYPE_1
@@ -4472,7 +4472,7 @@ c_define_builtins (tree va_list_ref_type
 #define DEF_POINTER_TYPE(ENUM, TYPE) \
   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
 
-#include "builtin-types.def"
+#include "builtin-types.h"
 
 #undef DEF_PRIMITIVE_TYPE
 #undef DEF_FUNCTION_TYPE_1
@@ -4500,7 +4500,7 @@ c_define_builtins (tree va_list_ref_type
 		   builtin_types[(int) LIBTYPE],                        \
 		   BOTH_P, FALLBACK_P, NONANSI_P,                       \
 		   built_in_attributes[(int) ATTRS], IMPLICIT);
-#include "builtins.def"
+#include "builtin-md.h"
 #undef DEF_BUILTIN
 
   targetm.init_builtins ();
@@ -5668,7 +5668,7 @@ c_init_attributes (void)
     = tree_cons (built_in_attributes[(int) PURPOSE],	\
 		 built_in_attributes[(int) VALUE],	\
 		 built_in_attributes[(int) CHAIN]);
-#include "builtin-attrs.def"
+#include "builtin-attrs.h"
 #undef DEF_ATTR_NULL_TREE
 #undef DEF_ATTR_INT
 #undef DEF_ATTR_IDENT
Index: gcc/lto/lto-lang.c
===================================================================
--- gcc/lto/lto-lang.c	(revision 171948)
+++ gcc/lto/lto-lang.c	(working copy)
@@ -1,5 +1,5 @@
 /* Language-dependent hooks for LTO.
-   Copyright 2009, 2010 Free Software Foundation, Inc.
+   Copyright 2009, 2010, 2011 Free Software Foundation, Inc.
    Contributed by CodeSourcery, Inc.
 
 This file is part of GCC.
@@ -98,7 +98,7 @@ enum built_in_attribute
 #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
 #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
-#include "builtin-attrs.def"
+#include "builtin-attrs.h"
 #undef DEF_ATTR_NULL_TREE
 #undef DEF_ATTR_INT
 #undef DEF_ATTR_IDENT
@@ -129,7 +129,7 @@ enum lto_builtin_type
 #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \
   NAME,
 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
-#include "builtin-types.def"
+#include "builtin-types.h"
 #undef DEF_PRIMITIVE_TYPE
 #undef DEF_FUNCTION_TYPE_0
 #undef DEF_FUNCTION_TYPE_1
@@ -160,7 +160,7 @@ static GTY(()) tree intmax_type_node;
 static GTY(()) tree uintmax_type_node;
 static GTY(()) tree signed_size_type_node;
 
-/* Flags needed to process builtins.def.  */
+/* Flags needed to process builtin-md.h.  */
 int flag_isoc94;
 int flag_isoc99;
 
@@ -474,7 +474,7 @@ def_fn_type (builtin_type def, builtin_t
   va_end (list);
 }
 
-/* Used to help initialize the builtin-types.def table.  When a type of
+/* Used to help initialize the builtin-types.h table.  When a type of
    the correct size doesn't exist, use error_mark_node instead of NULL.
    The later results in segfaults even when a decl using the type doesn't
    get invoked.  */
@@ -534,7 +534,7 @@ lto_init_attributes (void)
     = tree_cons (built_in_attributes[(int) PURPOSE],	\
 		 built_in_attributes[(int) VALUE],	\
 		 built_in_attributes[(int) CHAIN]);
-#include "builtin-attrs.def"
+#include "builtin-attrs.h"
 #undef DEF_ATTR_NULL_TREE
 #undef DEF_ATTR_INT
 #undef DEF_ATTR_IDENT
@@ -542,7 +542,7 @@ lto_init_attributes (void)
 }
 
 /* Create builtin types and functions.  VA_LIST_REF_TYPE_NODE and
-   VA_LIST_ARG_TYPE_NODE are used in builtin-types.def.  */
+   VA_LIST_ARG_TYPE_NODE are used in builtin-types.h.  */
 
 static void
 lto_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
@@ -583,7 +583,7 @@ lto_define_builtins (tree va_list_ref_ty
 #define DEF_POINTER_TYPE(ENUM, TYPE) \
   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
 
-#include "builtin-types.def"
+#include "builtin-types.h"
 
 #undef DEF_PRIMITIVE_TYPE
 #undef DEF_FUNCTION_TYPE_1
@@ -609,7 +609,7 @@ lto_define_builtins (tree va_list_ref_ty
       def_builtin_1 (ENUM, NAME, CLASS, builtin_types[(int) TYPE],	\
 		     builtin_types[(int) LIBTYPE], BOTH_P, FALLBACK_P,	\
 		     NONANSI_P, built_in_attributes[(int) ATTRS], IMPLICIT);
-#include "builtins.def"
+#include "builtin-md.h"
 #undef DEF_BUILTIN
 }
 
@@ -1025,7 +1025,7 @@ lto_register_builtin_type (tree type, co
 }
 
 /* Build nodes that would have be created by the C front-end; necessary
-   for including builtin-types.def and ultimately builtins.def.  */
+   for including builtin-types.h and ultimately builtin-md.h.  */
 
 static void
 lto_build_c_type_nodes (void)
Index: gcc/lto/Make-lang.in
===================================================================
--- gcc/lto/Make-lang.in	(revision 171947)
+++ gcc/lto/Make-lang.in	(working copy)
@@ -1,5 +1,5 @@
 # Top level -*- makefile -*- fragment for LTO
-#   Copyright (C) 2009, 2010
+#   Copyright (C) 2009, 2010, 2011
 #   Free Software Foundation, Inc.
 
 #This file is part of GCC.
@@ -79,7 +79,8 @@ $(LTO_EXE): $(LTO_OBJS) $(BACKEND) $(LIB
 lto/lto-lang.o: lto/lto-lang.c $(CONFIG_H) coretypes.h debug.h \
 	flags.h $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(SYSTEM_H) \
 	$(TARGET_H) $(LTO_H) $(GIMPLE_H) gtype-lto.h gt-lto-lto-lang.h \
-	$(EXPR_H) $(LTO_STREAMER_H)
+	$(EXPR_H) $(LTO_STREAMER_H) $(BUILTIN_ATTRS_H) $(BUILTIN_TYPES_H) \
+	$(BUILTIN_MD_H)
 lto/lto.o: lto/lto.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(OPTS_H) \
 	toplev.h $(TREE_H) $(DIAGNOSTIC_CORE_H) $(TM_H) \
 	$(CGRAPH_H) $(GGC_H) tree-ssa-operands.h $(TREE_PASS_H) \

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

* Re: [PATCH] centralize builtin function type building
  2011-04-22 19:28 ` Michael Meissner
@ 2011-04-22 19:46   ` Nathan Froyd
  0 siblings, 0 replies; 6+ messages in thread
From: Nathan Froyd @ 2011-04-22 19:46 UTC (permalink / raw)
  To: Michael Meissner, Kenneth Zadeck, gcc-patches

On Fri, Apr 22, 2011 at 02:58:31PM -0400, Michael Meissner wrote:
> On Thu, Apr 21, 2011 at 11:04:47AM -0400, Nathan Froyd wrote:
> > - centralizes some infrastructure for defining builtin function types
> >   for frontends by providing a common function that
> >   DEF_FUNCTION_TYPE_FOO macros can call; and
> > 
> > - in order to do that well, it also introduces
> >   build{,_varargs}_function_type_array for cases when
> >   build_function_type_list's interface doesn't work so well.
> 
> 1) For the DEF_FUNCTION_* replacements, the lines exceed the normal 79
>    character limits we use as coding guidelines.

Will fix.

> 2) I'm not a fan of having a varargs function with an explicit count.  I tend
>    to prefer a marker element (like NULL_TREE) as the last element.  In this
>    case, since it is being used in macros that do have fixed elements, it isn't
>    a problem.

We have both kinds of varargs usage in-tree; I think the explicit count
version ought to be preferred, as it makes sharing code between the
takes-varargs version and the takes-count-and-pointer (or the takes-VEC
or takes-std::vector) version easier.  (The explicit count version makes
future function overloading with takes-count-and-pointer more difficult,
though, and of course there's __attribute__((sentinel)) support for
varargs-with-marker functions.)

I suppose you could just write the macros to use
build_function_type_list instead, but it seems nice to delegate all the
accesses to someplace else.

> 3) I'm also not a fan of passing the index into the type array, instead of a
>    tree value to the call.  If you pass a tree, then it allows MD builtins to
>    call it before we switch to having the MD and front end builtins share the
>    bultin index.

Yes, I suppose so.

-Nathan

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

end of thread, other threads:[~2011-04-22 19:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-21 15:37 [PATCH] centralize builtin function type building Nathan Froyd
2011-04-21 15:54 ` Richard Guenther
2011-04-21 19:32   ` Michael Meissner
2011-04-22 16:59   ` Nathan Froyd
2011-04-22 19:28 ` Michael Meissner
2011-04-22 19:46   ` 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).