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]

[Patch, fortran] PR32239 Use builtin_powi


:ADDPATCH fortran:

Hi,

the attached patch changes gfortran to use builtin_powi for real**int4 powers. This enables potentially better optimization, as the middle-end is not aware of the inner workings of __gfortran_pow_rn_i4. However, at the moment the vectorizer only vectorizes builtin_pow if the exponent is either 2 or 0.5, whereas if we expand constant exponents in the gfortran frontend (gfc_conv_cst_int_power) it vectorizes for other constant integer powers as well (the expansion by the frontend generates a number of calls to builtin_pow with exponent 2.0). So I left that part alone for now, i.e. builtin_powi is used only for real**int4 when int4 is non-constant. Also, it unfortunately seems the middle-end is not able to do the sort of optimization suggested in the PR, but perhaps some day.

So I guess at the moment this is mostly a library bloat reduction patch, with some potential for better optimization in the future.

--
Janne Blomqvist
gcc/fortran:
	
2007-06-17  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/32239
	* trans-expr.c (gfc_conv_power_op): Use builtin_powi for
	real**int4 powers.
	* f95-lang.c (gfc_init_builtin_functions): Add builtin_powi to the
	builtins table.

	
libgfortran:
	
2007-06-17  Janne Blomqvist  <jb@gcc.gnu.org>

	PR fortran/32239
	* Makefile.am: Don't generate real**int4 pow functions.
	* gfortran.map: Remove real**int4 pow symbols.
	* Makefile.in: Regenerated.
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(revision 125765)
+++ gcc/fortran/trans-expr.c	(working copy)
@@ -780,9 +780,9 @@ gfc_conv_power_op (gfc_se * se, gfc_expr
   gfc_add_block_to_block (&se->pre, &rse.pre);
 
   if (expr->value.op.op2->ts.type == BT_INTEGER
-	 && expr->value.op.op2->expr_type == EXPR_CONSTANT)
+      && expr->value.op.op2->expr_type == EXPR_CONSTANT)
     if (gfc_conv_cst_int_power (se, lse.expr, rse.expr))
-      return;        
+      return;
 
   gfc_int4_type_node = gfc_get_int_type (4);
 
@@ -852,7 +852,30 @@ gfc_conv_power_op (gfc_se * se, gfc_expr
 	  break;
 
 	case BT_REAL:
-	  fndecl = gfor_fndecl_math_powi[kind][ikind].real;
+	  /* Use builtins for real ** int4.  */
+	  if (ikind == 0)
+	    {
+	      switch (kind)
+		{
+		case 0:
+		  fndecl = built_in_decls[BUILT_IN_POWIF];
+		  break;
+		
+		case 1:
+		  fndecl = built_in_decls[BUILT_IN_POWI];
+		  break;
+
+		case 2:
+		case 3:
+		  fndecl = built_in_decls[BUILT_IN_POWIL];
+		  break;
+
+		default:
+		  gcc_unreachable ();
+		}
+	    }
+	  else
+	    fndecl = gfor_fndecl_math_powi[kind][ikind].real;
 	  break;
 
 	case BT_COMPLEX:
Index: gcc/fortran/f95-lang.c
===================================================================
--- gcc/fortran/f95-lang.c	(revision 125765)
+++ gcc/fortran/f95-lang.c	(working copy)
@@ -950,6 +950,13 @@ gfc_init_builtin_functions (void)
 		      BUILT_IN_POW, "pow", true);
   gfc_define_builtin ("__builtin_powf", mfunc_float[1], 
 		      BUILT_IN_POWF, "powf", true);
+  gfc_define_builtin ("__builtin_powil", mfunc_longdouble[2], 
+		      BUILT_IN_POWIL, "powil", true);
+  gfc_define_builtin ("__builtin_powi", mfunc_double[2], 
+		      BUILT_IN_POWI, "powi", true);
+  gfc_define_builtin ("__builtin_powif", mfunc_float[2], 
+		      BUILT_IN_POWIF, "powif", true);
+
 
   if (TARGET_C99_FUNCTIONS)
     {
Index: libgfortran/Makefile.am
===================================================================
--- libgfortran/Makefile.am	(revision 125765)
+++ libgfortran/Makefile.am	(working copy)
@@ -430,10 +430,6 @@ i_pow_c = \
 $(srcdir)/generated/pow_i4_i4.c \
 $(srcdir)/generated/pow_i8_i4.c \
 $(srcdir)/generated/pow_i16_i4.c \
-$(srcdir)/generated/pow_r4_i4.c \
-$(srcdir)/generated/pow_r8_i4.c \
-$(srcdir)/generated/pow_r10_i4.c \
-$(srcdir)/generated/pow_r16_i4.c \
 $(srcdir)/generated/pow_c4_i4.c \
 $(srcdir)/generated/pow_c8_i4.c \
 $(srcdir)/generated/pow_c10_i4.c \
Index: libgfortran/gfortran.map
===================================================================
--- libgfortran/gfortran.map	(revision 125765)
+++ libgfortran/gfortran.map	(working copy)
@@ -529,16 +529,12 @@ GFORTRAN_1.0 {
     _gfortran_pow_i8_i4;
     _gfortran_pow_i8_i8;
     _gfortran_pow_r10_i16;
-    _gfortran_pow_r10_i4;
     _gfortran_pow_r10_i8;
     _gfortran_pow_r16_i16;
-    _gfortran_pow_r16_i4;
     _gfortran_pow_r16_i8;
     _gfortran_pow_r4_i16;
-    _gfortran_pow_r4_i4;
     _gfortran_pow_r4_i8;
     _gfortran_pow_r8_i16;
-    _gfortran_pow_r8_i4;
     _gfortran_pow_r8_i8;
     _gfortran_product_c10;
     _gfortran_product_c16;

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