This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, fortran] PR32239 Use builtin_powi
- From: Janne Blomqvist <blomqvist dot janne at gmail dot com>
- To: gfortran <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 17 Jun 2007 14:39:00 +0300
- Subject: [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;