This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gfortran] Builtin functions


The attached patch maked gfortran handle builtin functions that same way as 
java and g77. It avoids having to deal with all the messy c-specific mess 
associated with using builtins.def.

Applied to tree-ssa branch.

I'll post a followup patch to revert the signed_size_type hack once it's 
tested.

Paul

2003-08-30  Paul Brook  <paul@nowt.org>

	* f95-lang.c (builtin_function): Remove #if 0 code.
	(gfc_define_builtin): New function.
	(gfc_init_builtin_functions): Use mathbuiltins.def not ../builtins.def.
	* mathbuiltins.def: New file.
	* trans-intrinsic.c (gfc_intrinsic_map_t): Add builtin code fields.
	(gfc_intrinsic_map): Use mathbuiltins.def.
	(gfc_intrinsic_builtin_t): Remove.
	(gfc_build_intrinsic_lib_fndecls): Update.
	* trans-types.c (gfc_init_types): Remove redundant initilaization of
	signed_size_type_node.
diff -uNprxCVS clean/tree-ssa/gcc/fortran/f95-lang.c gcc/gcc/fortran/f95-lang.c
--- clean/tree-ssa/gcc/fortran/f95-lang.c	2003-07-26 00:07:31.000000000 +0100
+++ gcc/gcc/fortran/f95-lang.c	2003-08-30 18:28:40.000000000 +0100
@@ -815,7 +815,8 @@ builtin_function (const char *name,
 		  tree type,
 		  int function_code,
 		  enum built_in_class class,
-		  const char *library_name, tree attrs ATTRIBUTE_UNUSED)
+		  const char *library_name,
+		  tree attrs ATTRIBUTE_UNUSED)
 {
   tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
   DECL_EXTERNAL (decl) = 1;
@@ -826,197 +827,80 @@ builtin_function (const char *name,
   pushdecl (decl);
   DECL_BUILT_IN_CLASS (decl) = class;
   DECL_FUNCTION_CODE (decl) = function_code;
-
-#if 0
-  if (attrs)
-    decl_attributes (&decl, attrs, ATTR_FLAG_BUILT_IN);
-  else
-    decl_attributes (&decl, NULL_TREE, 0);
-#endif
   return decl;
 }
 
-#define flag_isoc99 0
-enum built_in_attribute
+
+static void
+gfc_define_builtin (const char * name,
+		    tree type,
+		    int code,
+		    const char * library_name)
 {
-#define DEF_ATTR_NULL_TREE(ENUM) ENUM,
-#define DEF_ATTR_INT(ENUM, VALUE) ENUM,
-#define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
-#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
-#define DEF_FN_ATTR(NAME, ATTRS, PREDICATE)	/* No entry needed in enum.  */
-#include "builtin-attrs.def"
-#undef DEF_ATTR_NULL_TREE
-#undef DEF_ATTR_INT
-#undef DEF_ATTR_IDENT
-#undef DEF_ATTR_TREE_LIST
-#undef DEF_FN_ATTR
-  ATTR_LAST
-};
+  built_in_decls[code] = builtin_function (name, type, code, BUILT_IN_NORMAL,
+      library_name, NULL_TREE);
+}
 
-/* Initialisation of builtin function nodes.  Copied from c-common.c.  */
+
+#define DEFINE_MATH_BUILTIN(code, name, nargs) \
+    gfc_define_builtin ("__builtin_" name, mfunc_double[nargs], \
+			BUILT_IN_ ## code, name); \
+    gfc_define_builtin ("__builtin_" name "f", mfunc_float[nargs], \
+			BUILT_IN_ ## code ## F, name "f");
+
+/* Initialisation of builtin function nodes.  */
 static void
 gfc_init_builtin_functions (void)
 {
-  enum builtin_type
-  {
-#define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
-#define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
-#define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
-#define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
-#define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
-#define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
-#define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
-#define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
-#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
-#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
-#define DEF_POINTER_TYPE(NAME, TYPE) NAME,
-#include "builtin-types.def"
-#undef DEF_PRIMITIVE_TYPE
-#undef DEF_FUNCTION_TYPE_0
-#undef DEF_FUNCTION_TYPE_1
-#undef DEF_FUNCTION_TYPE_2
-#undef DEF_FUNCTION_TYPE_3
-#undef DEF_FUNCTION_TYPE_4
-#undef DEF_FUNCTION_TYPE_VAR_0
-#undef DEF_FUNCTION_TYPE_VAR_1
-#undef DEF_FUNCTION_TYPE_VAR_2
-#undef DEF_FUNCTION_TYPE_VAR_3
-#undef DEF_POINTER_TYPE
-    BT_LAST
-  };
-
-  typedef enum builtin_type builtin_type;
-
-  tree builtin_types[(int) BT_LAST];
-  tree va_list_ref_type_node;
-  tree va_list_arg_type_node;
-
-  if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
-    {
-      va_list_arg_type_node = va_list_ref_type_node =
-	build_pointer_type (TREE_TYPE (va_list_type_node));
-    }
-  else
-    {
-      va_list_arg_type_node = va_list_type_node;
-      va_list_ref_type_node = build_reference_type (va_list_type_node);
-    }
-
-#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 (builtin_types[(int) RETURN],	\
-			   void_list_node);
-#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1)				\
-  builtin_types[(int) ENUM]						\
-    = build_function_type (builtin_types[(int) RETURN],			\
-			   tree_cons (NULL_TREE,			\
-				      builtin_types[(int) ARG1],	\
-				      void_list_node));
-#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2)	\
-  builtin_types[(int) ENUM]				\
-    = build_function_type 				\
-      (builtin_types[(int) RETURN],			\
-       tree_cons (NULL_TREE,				\
-		  builtin_types[(int) ARG1],		\
-		  tree_cons (NULL_TREE,			\
-			     builtin_types[(int) ARG2],	\
-			     void_list_node)));
-#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3)		 \
-  builtin_types[(int) ENUM]						 \
-    = build_function_type						 \
-      (builtin_types[(int) RETURN],					 \
-       tree_cons (NULL_TREE,						 \
-		  builtin_types[(int) ARG1],				 \
-		  tree_cons (NULL_TREE,					 \
-			     builtin_types[(int) ARG2],			 \
-			     tree_cons (NULL_TREE,			 \
-					builtin_types[(int) ARG3],	 \
-					void_list_node))));
-#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4)	\
-  builtin_types[(int) ENUM]						\
-    = build_function_type						\
-      (builtin_types[(int) RETURN],					\
-       tree_cons (NULL_TREE,						\
-		  builtin_types[(int) ARG1],				\
-		  tree_cons (NULL_TREE,					\
-			     builtin_types[(int) ARG2],			\
-			     tree_cons 					\
-			     (NULL_TREE,				\
-			      builtin_types[(int) ARG3],	 	\
-			      tree_cons (NULL_TREE,			\
-					 builtin_types[(int) ARG4],	\
-					 void_list_node)))));
-#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN)				\
-  builtin_types[(int) ENUM]						\
-    = build_function_type (builtin_types[(int) RETURN], NULL_TREE);
-#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1)			 \
-   builtin_types[(int) ENUM]						 \
-    = build_function_type (builtin_types[(int) RETURN], 		 \
-			   tree_cons (NULL_TREE,			 \
-				      builtin_types[(int) ARG1],	 \
-				      NULL_TREE));
-
-#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2)	\
-   builtin_types[(int) ENUM]					\
-    = build_function_type 					\
-      (builtin_types[(int) RETURN],				\
-       tree_cons (NULL_TREE,					\
-		  builtin_types[(int) ARG1],			\
-		  tree_cons (NULL_TREE,				\
-			     builtin_types[(int) ARG2],		\
-			     NULL_TREE)));
-
-#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3)	      \
-   builtin_types[(int) ENUM]					      \
-    = build_function_type 					      \
-      (builtin_types[(int) RETURN],				      \
-       tree_cons (NULL_TREE,					      \
-		  builtin_types[(int) ARG1],			      \
-		  tree_cons (NULL_TREE,				      \
-			     builtin_types[(int) ARG2],		      \
-		             tree_cons (NULL_TREE,	              \
-			                builtin_types[(int) ARG3],    \
-			                NULL_TREE))));
-#define DEF_POINTER_TYPE(ENUM, TYPE)			\
-  builtin_types[(int) ENUM]				\
-    = build_pointer_type (builtin_types[(int) TYPE]);
-#include "builtin-types.def"
-#undef DEF_PRIMITIVE_TYPE
-#undef DEF_FUNCTION_TYPE_1
-#undef DEF_FUNCTION_TYPE_2
-#undef DEF_FUNCTION_TYPE_3
-#undef DEF_FUNCTION_TYPE_4
-#undef DEF_FUNCTION_TYPE_VAR_0
-#undef DEF_FUNCTION_TYPE_VAR_1
-#undef DEF_FUNCTION_TYPE_VAR_2
-#undef DEF_FUNCTION_TYPE_VAR_3
-#undef DEF_POINTER_TYPE
-
-#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE,			\
-		    BOTH_P, FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT)	\
-  if (NAME)								\
-    {									\
-      tree decl;							\
-									\
-      if (strncmp (NAME, "__builtin_", strlen ("__builtin_")) != 0)	\
-	abort ();							\
-									\
-	decl = builtin_function (NAME, builtin_types[TYPE], ENUM,	\
-				 CLASS,					\
-				 (FALLBACK_P				\
-				  ? (NAME + strlen ("__builtin_"))	\
-				  : NULL),				\
-				 NULL);	                                \
-									\
-      built_in_decls[(int) ENUM] = decl;				\
-    }
-#include "builtins.def"
-#undef DEF_BUILTIN
-
-  main_identifier_node = get_identifier ("main");
+  tree mfunc_float[2];
+  tree mfunc_double[2];
+  tree ftype_expect;
+  tree ftype_memcpy;
+  tree tmp;
+  tree voidchain;
+
+  voidchain = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
+
+  tmp = tree_cons (NULL_TREE, float_type_node, voidchain);
+  mfunc_float[1] = build_function_type (float_type_node, tmp);
+  tmp = tree_cons (NULL_TREE, float_type_node, tmp);
+  mfunc_float[2] = build_function_type (float_type_node, tmp);
+
+  tmp = tree_cons (NULL_TREE, double_type_node, voidchain);
+  mfunc_double[1] = build_function_type (double_type_node, tmp);
+  tmp = tree_cons (NULL_TREE, double_type_node, tmp);
+  mfunc_double[2] = build_function_type (double_type_node, tmp);
+
+  tmp = tree_cons (NULL_TREE, long_integer_type_node, voidchain);
+  tmp = tree_cons (NULL_TREE, long_integer_type_node, tmp);
+  ftype_expect = build_function_type (long_integer_type_node, tmp);
+
+  tmp = tree_cons (NULL_TREE, size_type_node, voidchain);
+  tmp = tree_cons (NULL_TREE, pvoid_type_node, voidchain);
+  tmp = tree_cons (NULL_TREE, pvoid_type_node, voidchain);
+  ftype_memcpy = build_function_type (pvoid_type_node, tmp);
+
+#include "mathbuiltins.def"
+
+  /* We define there seperately as the fortran versions have different
+     semantics (they return an integer type) */
+  gfc_define_builtin ("__builtin_floor", mfunc_double[1], 
+		      BUILT_IN_FLOOR, "floor");
+  gfc_define_builtin ("__builtin_floorf", mfunc_float[1], 
+		      BUILT_IN_FLOORF, "floorf");
+  gfc_define_builtin ("__builtin_round", mfunc_double[1], 
+		      BUILT_IN_ROUND, "round");
+  gfc_define_builtin ("__builtin_roundf", mfunc_float[1], 
+		      BUILT_IN_ROUNDF, "roundf");
+
+  /* Other builtin functions we use.  */
+  gfc_define_builtin ("__builtin_expect", ftype_expect,
+		      BUILT_IN_EXPECT, "expect");
+  gfc_define_builtin ("__builtin_memcpy", ftype_memcpy,
+		      BUILT_IN_MEMCPY, "memcpy");
 }
 
+#undef DEFINE_MATH_BUILTIN
+
 #include "gt-fortran-f95-lang.h"
 #include "gtype-fortran.h"
diff -uNprxCVS clean/tree-ssa/gcc/fortran/mathbuiltins.def gcc/gcc/fortran/mathbuiltins.def
--- clean/tree-ssa/gcc/fortran/mathbuiltins.def	1970-01-01 01:00:00.000000000 +0100
+++ gcc/gcc/fortran/mathbuiltins.def	2003-08-30 17:21:06.000000000 +0100
@@ -0,0 +1,8 @@
+DEFINE_MATH_BUILTIN (ATAN, "atan", 1)
+DEFINE_MATH_BUILTIN (ATAN2, "atan2", 2)
+DEFINE_MATH_BUILTIN (COS, "cos", 1)
+DEFINE_MATH_BUILTIN (EXP, "exp", 1)
+DEFINE_MATH_BUILTIN (LOG, "log", 1)
+DEFINE_MATH_BUILTIN (SIN, "sin", 1)
+DEFINE_MATH_BUILTIN (SQRT, "sqrt", 1)
+DEFINE_MATH_BUILTIN (TAN, "tan", 1)
diff -uNprxCVS clean/tree-ssa/gcc/fortran/trans-intrinsic.c gcc/gcc/fortran/trans-intrinsic.c
--- clean/tree-ssa/gcc/fortran/trans-intrinsic.c	2003-08-22 23:46:18.000000000 +0100
+++ gcc/gcc/fortran/trans-intrinsic.c	2003-08-30 18:16:59.000000000 +0100
@@ -52,6 +52,8 @@ typedef struct gfc_intrinsic_map_t	GTY((
      garbage collection/gengtype parsing mechanism.  */
   const enum gfc_generic_isym_id id;
   const char *name;
+  const int code4;
+  const int code8;
   tree GTY(()) real4_decl;
   tree GTY(()) real8_decl;
   tree GTY(()) complex4_decl;
@@ -59,41 +61,28 @@ typedef struct gfc_intrinsic_map_t	GTY((
 }
 gfc_intrinsic_map_t;
 
-#define I_LIB(id, name) {id, name, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
+#define I_LIB(id, name) {GFC_ISYM_ ## id, name, \
+    END_BUILTINS, END_BUILTINS, \
+    NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
+#define DEFINE_MATH_BUILTIN(id, name, nargs) {GFC_ISYM_ ## id, name, \
+    BUILT_IN_ ## id ## F, BUILT_IN_ ## id, \
+    NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
 {
   /* Math functions.  These are in libm.  */
-  I_LIB (GFC_ISYM_SIN, "sin")
-  I_LIB (GFC_ISYM_COS, "cos")
-  I_LIB (GFC_ISYM_SQRT, "sqrt")
-  I_LIB (GFC_ISYM_TAN, "tan")
-  I_LIB (GFC_ISYM_ASIN, "asin")
-  I_LIB (GFC_ISYM_ACOS, "acos")
-  I_LIB (GFC_ISYM_ATAN, "atan")
-  I_LIB (GFC_ISYM_ATAN2, "atan2")
-  I_LIB (GFC_ISYM_SINH, "sinh")
-  I_LIB (GFC_ISYM_COSH, "cosh")
-  I_LIB (GFC_ISYM_TANH, "tanh")
-  I_LIB (GFC_ISYM_EXP, "exp")
-  I_LIB (GFC_ISYM_LOG, "log")
-  I_LIB (GFC_ISYM_LOG10, "log10") I_LIB (GFC_ISYM_NONE, NULL)
-};
-#undef I_LIB
-
-typedef struct
-{
-  const gfc_generic_isym_id id;
-  const int code4;
-  const int code8;
-}
-gfc_builtin_intrinsic_t;
+  I_LIB	    (ACOS,  "acos")
+  I_LIB	    (ASIN,  "asin")
+  I_LIB	    (COSH,  "cosh")
+  I_LIB	    (LOG10, "log10")
+  I_LIB	    (SINH,  "sinh")
+  I_LIB	    (TANH,  "tanh")
+  /* Also the builtin math functions.  */
+#include "mathbuiltins.def"
 
-static const gfc_builtin_intrinsic_t gfc_builtin_intrinsics[] = {
-  {GFC_ISYM_SIN, BUILT_IN_SINF, BUILT_IN_SIN},
-  {GFC_ISYM_COS, BUILT_IN_COSF, BUILT_IN_COS},
-  {GFC_ISYM_SQRT, BUILT_IN_SQRTF, BUILT_IN_SQRT},
-  {GFC_ISYM_NONE, 0, 0}
+  I_LIB (NONE, NULL)
 };
+#undef I_LIB
+#undef I_BUILTIN
 
 
 /* Evaluate the arguments to an intrinsic function.  */
@@ -404,21 +393,15 @@ gfc_conv_intrinsic_conjg (gfc_se * se, g
 void
 gfc_build_intrinsic_lib_fndecls (void)
 {
-  const gfc_builtin_intrinsic_t *i;
   gfc_intrinsic_map_t *m;
 
   /* Add GCC builtin functions.  */
-  for (i = gfc_builtin_intrinsics; i->id != GFC_ISYM_NONE; i++)
+  for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
     {
-      for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
-	{
-	  if (m->id == i->id)
-	    break;
-	}
-      assert (m->id != GFC_ISYM_NONE);
-
-      m->real4_decl = built_in_decls[i->code4];
-      m->real8_decl = built_in_decls[i->code8];
+      if (m->code4 != END_BUILTINS)
+        m->real4_decl = built_in_decls[m->code4];
+      if (m->code8 != END_BUILTINS)
+	m->real8_decl = built_in_decls[m->code8];
     }
 }
 
diff -uNprxCVS clean/tree-ssa/gcc/fortran/trans-types.c gcc/gcc/fortran/trans-types.c
--- clean/tree-ssa/gcc/fortran/trans-types.c	2003-08-21 23:41:42.000000000 +0100
+++ gcc/gcc/fortran/trans-types.c	2003-08-30 18:51:23.000000000 +0100
@@ -177,7 +177,6 @@ gfc_init_types (void)
   TREE_TYPE (boolean_true_node) = boolean_type_node;
   boolean_false_node = build_int_2 (0, 0);
   TREE_TYPE (boolean_false_node) = boolean_type_node;
-  signed_size_type_node = size_type_node;
 }
 
 /* Get a type node for an integer kind */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]