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]

[FORTRAN PATCH] Use more mathematical builtins


The following patch is a tweak to the g77 front-end to make more use
of GCC's built-in mathematical functions.  Previously g77 used GCC
builtins for cos, sin and sqrt.  With this patch, it does the same
for atan2, exp, floor, fmod, log and pow.  This enables FORTRAN to
take advantage of the middle-end's constant folding transformations
and (when available) the inline intrinsic implementations provided
by the target's backend.

The g77 testsuite showed up a bug in duplicate_decls when calling
__builtin_fmod, which is always converted straight to a standard C
library call.  The code to call COPY_DECL_ASSEMBLER_NAME is copied
directly from the C front-end's duplicate_decls in c-decl.c.  This
is another example of a change to duplicate_decls since the code
was originally duplicated into the FORTRAN front-end.

The following patch has been tested on i686-pc-linux-gnu, by a full
bootstrap configured with --enable-languages=c,f77 and a top-level
"make -k check" with no new regressions.  I've also confirmed by
hand that "FOO = EXP(0.0)" no longer calls the C library but instead
assigns 1.0 to FOO at run-time.

Ok for mainline?


2003-05-11  Roger Sayle  <roger@eyesopen.com>

	* com.c (ffecom_init_0): Define built-in functions for atan2,
	exp, floor, fmod, log and pow.
	(duplicate_decls): Preserve assembler name when redeclaring a
	built-in.
	* com-rt.def: Implement using the built-in forms of the above
	functions rather than calling the standard C library directly.
	Correct some of the run-time prototype "codes".


Index: com.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/f/com.c,v
retrieving revision 1.193
diff -c -3 -p -r1.193 com.c
*** com.c	8 May 2003 13:13:57 -0000	1.193
--- com.c	11 May 2003 19:32:19 -0000
*************** ffecom_init_0 ()
*** 11187,11195 ****
    tree field;
    ffetype type;
    ffetype base_type;
!   tree double_ftype_double;
!   tree float_ftype_float;
!   tree ldouble_ftype_ldouble;
    tree ffecom_tree_ptr_to_fun_type_void;

    /* This block of code comes from the now-obsolete cktyps.c.  It checks
--- 11187,11195 ----
    tree field;
    ffetype type;
    ffetype base_type;
!   tree double_ftype_double, double_ftype_double_double;
!   tree float_ftype_float, float_ftype_float_float;
!   tree ldouble_ftype_ldouble, ldouble_ftype_ldouble_ldouble;
    tree ffecom_tree_ptr_to_fun_type_void;

    /* This block of code comes from the now-obsolete cktyps.c.  It checks
*************** ffecom_init_0 ()
*** 11322,11339 ****

    endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);

!   float_ftype_float
!     = build_function_type (float_type_node,
! 			   tree_cons (NULL_TREE, float_type_node, endlink));
!
!   double_ftype_double
!     = build_function_type (double_type_node,
! 			   tree_cons (NULL_TREE, double_type_node, endlink));
!
!   ldouble_ftype_ldouble
!     = build_function_type (long_double_type_node,
! 			   tree_cons (NULL_TREE, long_double_type_node,
! 				      endlink));

    for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
      for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
--- 11322,11342 ----

    endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);

!   t = tree_cons (NULL_TREE, float_type_node, endlink);
!   float_ftype_float = build_function_type (float_type_node, t);
!   t = tree_cons (NULL_TREE, float_type_node, t);
!   float_ftype_float_float = build_function_type (float_type_node, t);
!
!   t = tree_cons (NULL_TREE, double_type_node, endlink);
!   double_ftype_double = build_function_type (double_type_node, t);
!   t = tree_cons (NULL_TREE, double_type_node, t);
!   double_ftype_double_double = build_function_type (double_type_node, t);
!
!   t = tree_cons (NULL_TREE, long_double_type_node, endlink);
!   ldouble_ftype_ldouble = build_function_type (long_double_type_node, t);
!   t = tree_cons (NULL_TREE, long_double_type_node, t);
!   ldouble_ftype_ldouble_ldouble = build_function_type (long_double_type_node,
!                                                        t);

    for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
      for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
*************** ffecom_init_0 ()
*** 11750,11767 ****
    ffecom_tree_blockdata_type
      = build_function_type (void_type_node, NULL_TREE);

!   builtin_function ("__builtin_sqrtf", float_ftype_float,
! 		    BUILT_IN_SQRTF, BUILT_IN_NORMAL, "sqrtf", NULL_TREE);
!   builtin_function ("__builtin_sqrt", double_ftype_double,
! 		    BUILT_IN_SQRT, BUILT_IN_NORMAL, "sqrt", NULL_TREE);
!   builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
! 		    BUILT_IN_SQRTL, BUILT_IN_NORMAL, "sqrtl", NULL_TREE);
!   builtin_function ("__builtin_sinf", float_ftype_float,
! 		    BUILT_IN_SINF, BUILT_IN_NORMAL, "sinf", NULL_TREE);
!   builtin_function ("__builtin_sin", double_ftype_double,
! 		    BUILT_IN_SIN, BUILT_IN_NORMAL, "sin", NULL_TREE);
!   builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
! 		    BUILT_IN_SINL, BUILT_IN_NORMAL, "sinl", NULL_TREE);
    builtin_function ("__builtin_cosf", float_ftype_float,
  		    BUILT_IN_COSF, BUILT_IN_NORMAL, "cosf", NULL_TREE);
    builtin_function ("__builtin_cos", double_ftype_double,
--- 11753,11765 ----
    ffecom_tree_blockdata_type
      = build_function_type (void_type_node, NULL_TREE);

!   builtin_function ("__builtin_atan2f", float_ftype_float_float,
! 		    BUILT_IN_ATAN2F, BUILT_IN_NORMAL, "atan2f", NULL_TREE);
!   builtin_function ("__builtin_atan2", double_ftype_double_double,
! 		    BUILT_IN_ATAN2, BUILT_IN_NORMAL, "atan2", NULL_TREE);
!   builtin_function ("__builtin_atan2l", ldouble_ftype_ldouble_ldouble,
! 		    BUILT_IN_ATAN2L, BUILT_IN_NORMAL, "atan2l", NULL_TREE);
!
    builtin_function ("__builtin_cosf", float_ftype_float,
  		    BUILT_IN_COSF, BUILT_IN_NORMAL, "cosf", NULL_TREE);
    builtin_function ("__builtin_cos", double_ftype_double,
*************** ffecom_init_0 ()
*** 11769,11774 ****
--- 11767,11821 ----
    builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
  		    BUILT_IN_COSL, BUILT_IN_NORMAL, "cosl", NULL_TREE);

+   builtin_function ("__builtin_expf", float_ftype_float,
+ 		    BUILT_IN_EXPF, BUILT_IN_NORMAL, "expf", NULL_TREE);
+   builtin_function ("__builtin_exp", double_ftype_double,
+ 		    BUILT_IN_EXP, BUILT_IN_NORMAL, "exp", NULL_TREE);
+   builtin_function ("__builtin_expl", ldouble_ftype_ldouble,
+ 		    BUILT_IN_EXPL, BUILT_IN_NORMAL, "expl", NULL_TREE);
+
+   builtin_function ("__builtin_floorf", float_ftype_float,
+ 		    BUILT_IN_FLOORF, BUILT_IN_NORMAL, "floorf", NULL_TREE);
+   builtin_function ("__builtin_floor", double_ftype_double,
+ 		    BUILT_IN_FLOOR, BUILT_IN_NORMAL, "floor", NULL_TREE);
+   builtin_function ("__builtin_floorl", ldouble_ftype_ldouble,
+ 		    BUILT_IN_FLOORL, BUILT_IN_NORMAL, "floorl", NULL_TREE);
+
+   builtin_function ("__builtin_fmodf", float_ftype_float_float,
+ 		    BUILT_IN_FMODF, BUILT_IN_NORMAL, "fmodf", NULL_TREE);
+   builtin_function ("__builtin_fmod", double_ftype_double_double,
+ 		    BUILT_IN_FMOD, BUILT_IN_NORMAL, "fmod", NULL_TREE);
+   builtin_function ("__builtin_fmodl", ldouble_ftype_ldouble_ldouble,
+ 		    BUILT_IN_FMODL, BUILT_IN_NORMAL, "fmodl", NULL_TREE);
+
+   builtin_function ("__builtin_logf", float_ftype_float,
+ 		    BUILT_IN_LOGF, BUILT_IN_NORMAL, "logf", NULL_TREE);
+   builtin_function ("__builtin_log", double_ftype_double,
+ 		    BUILT_IN_LOG, BUILT_IN_NORMAL, "log", NULL_TREE);
+   builtin_function ("__builtin_logl", ldouble_ftype_ldouble,
+ 		    BUILT_IN_LOGL, BUILT_IN_NORMAL, "logl", NULL_TREE);
+
+   builtin_function ("__builtin_powf", float_ftype_float_float,
+ 		    BUILT_IN_POWF, BUILT_IN_NORMAL, "powf", NULL_TREE);
+   builtin_function ("__builtin_pow", double_ftype_double_double,
+ 		    BUILT_IN_POW, BUILT_IN_NORMAL, "pow", NULL_TREE);
+   builtin_function ("__builtin_powl", ldouble_ftype_ldouble_ldouble,
+ 		    BUILT_IN_POWL, BUILT_IN_NORMAL, "powl", NULL_TREE);
+
+   builtin_function ("__builtin_sinf", float_ftype_float,
+ 		    BUILT_IN_SINF, BUILT_IN_NORMAL, "sinf", NULL_TREE);
+   builtin_function ("__builtin_sin", double_ftype_double,
+ 		    BUILT_IN_SIN, BUILT_IN_NORMAL, "sin", NULL_TREE);
+   builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
+ 		    BUILT_IN_SINL, BUILT_IN_NORMAL, "sinl", NULL_TREE);
+
+   builtin_function ("__builtin_sqrtf", float_ftype_float,
+ 		    BUILT_IN_SQRTF, BUILT_IN_NORMAL, "sqrtf", NULL_TREE);
+   builtin_function ("__builtin_sqrt", double_ftype_double,
+ 		    BUILT_IN_SQRT, BUILT_IN_NORMAL, "sqrt", NULL_TREE);
+   builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
+ 		    BUILT_IN_SQRTL, BUILT_IN_NORMAL, "sqrtl", NULL_TREE);
+
    pedantic_lvalues = FALSE;

    ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
*************** duplicate_decls (tree newdecl, tree oldd
*** 13342,13347 ****
--- 13389,13397 ----
  	 are assigned.  */
        if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
  	DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
+
+       /* Copy the assembler name.  */
+       COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);

        if (TREE_CODE (newdecl) == FUNCTION_DECL)
  	{
Index: com-rt.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/f/com-rt.def,v
retrieving revision 1.13
diff -c -3 -p -r1.13 com-rt.def
*** com-rt.def	14 Dec 2001 21:06:18 -0000	1.13
--- com-rt.def	11 May 2003 19:32:19 -0000
*************** DEFGFRT (FFECOM_gfrtAMOD, "r_mod", FFECO
*** 128,134 ****
  DEFGFRT (FFECOM_gfrtANINT, "r_nint", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, FALSE)
  DEFGFRT (FFECOM_gfrtASIN, "r_asin", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, FALSE)
  DEFGFRT (FFECOM_gfrtATAN, "r_atan", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, FALSE)
! DEFGFRT (FFECOM_gfrtATAN2, "r_atn2", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, FALSE)
  DEFGFRT (FFECOM_gfrtCABS, "c_abs", FFECOM_rttypeREAL_F2C_, "&c", FALSE, FALSE, FALSE)
  DEFGFRT (FFECOM_gfrtCCOS, "c_cos", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE, FALSE)
  DEFGFRT (FFECOM_gfrtCEXP, "c_exp", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE, FALSE)
--- 128,134 ----
  DEFGFRT (FFECOM_gfrtANINT, "r_nint", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, FALSE)
  DEFGFRT (FFECOM_gfrtASIN, "r_asin", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, FALSE)
  DEFGFRT (FFECOM_gfrtATAN, "r_atan", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, FALSE)
! DEFGFRT (FFECOM_gfrtATAN2, "r_atn2", FFECOM_rttypeREAL_F2C_, "&f&f", FALSE, FALSE, FALSE)
  DEFGFRT (FFECOM_gfrtCABS, "c_abs", FFECOM_rttypeREAL_F2C_, "&c", FALSE, FALSE, FALSE)
  DEFGFRT (FFECOM_gfrtCCOS, "c_cos", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE, FALSE)
  DEFGFRT (FFECOM_gfrtCEXP, "c_exp", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE, FALSE)
*************** DEFGFRT (FFECOM_gfrtDIMAG, "d_imag", FFE
*** 260,276 ****
  DEFGFRT (FFECOM_gfrtL_ACOS, "acos", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_ASIN, "asin", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_ATAN, "atan", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_ATAN2, "atan2", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_COS, "__builtin_cos", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_COSH, "cosh", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_ERF, "erf", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_ERFC, "erfc", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_EXP, "exp", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_FLOOR, "floor", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_FMOD, "fmod", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_LOG, "log", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_LOG10, "log10", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_POW, "pow", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_SIN, "__builtin_sin", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_SINH, "sinh", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_SQRT, "__builtin_sqrt", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
--- 260,276 ----
  DEFGFRT (FFECOM_gfrtL_ACOS, "acos", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_ASIN, "asin", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_ATAN, "atan", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_ATAN2, "__builtin_atan2", FFECOM_rttypeDOUBLE_, "dd", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_COS, "__builtin_cos", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_COSH, "cosh", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_ERF, "erf", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_ERFC, "erfc", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_EXP, "__builtin_exp", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_FLOOR, "__builtin_floor", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_FMOD, "__builtin_fmod", FFECOM_rttypeDOUBLE_, "dd", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_LOG, "__builtin_log", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_LOG10, "log10", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
! DEFGFRT (FFECOM_gfrtL_POW, "__builtin_pow", FFECOM_rttypeDOUBLE_, "dd", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_SIN, "__builtin_sin", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_SINH, "sinh", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
  DEFGFRT (FFECOM_gfrtL_SQRT, "__builtin_sqrt", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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