This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, Fortran] PR 43205 - Null initialization of static variables
- From: Tobias Burnus <burnus at net-b dot de>
- To: gfortran <fortran at gcc dot gnu dot org>, gcc patches <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 28 Feb 2010 15:38:29 +0100
- Subject: [Patch, Fortran] PR 43205 - Null initialization of static variables
As reported in the PR, gfortran takes very long to compile:
subroutine testproblem
integer nsub_sta(11146, 2000), nsub_sto(11146, 2000)
write (*,*) nsub_sta(1,1)
write (*,*) nsub_sto(1,1)
end
with the option -fno-automatic (implicit SAVE, i.e. static memory for
all local variables) if used with -finit-local-zero. The reason is that
gfortran generates:
static integer(kind=4) nsub_sta[22292000] = {0, 0, 0, 0, 0, 0, 0, .... };
which takes extremely long to process. However, for zero initialization
this is equivalent to:
static integer(kind=4) nsub_sta[22292000] = {};
which the attached patch does and which reduces the compile time from
several minutes to 0.037s. The modification was motivated by
gfc_trans_assignment, which already covered this special case.
Build and tested on x86-64-linux. The regression test is currently running.
OK for the trunk? Do we need a test case for this?
Tobias
2010-02-28 Tobias Burnus <burnus@net-b.de>
PR fortran/43205
* trans-expr.c (is_zero_initializer_p): Move up in the file.
(gfc_conv_initializer): Handle zero initializer as special case.
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c (Revision 157119)
+++ gcc/fortran/trans-expr.c (Arbeitskopie)
@@ -3910,6 +3910,43 @@ gfc_conv_function_expr (gfc_se * se, gfc
}
+/* Determine whether the given EXPR_CONSTANT is a zero initializer. */
+
+static bool
+is_zero_initializer_p (gfc_expr * expr)
+{
+ if (expr->expr_type != EXPR_CONSTANT)
+ return false;
+
+ /* We ignore constants with prescribed memory representations for now. */
+ if (expr->representation.string)
+ return false;
+
+ switch (expr->ts.type)
+ {
+ case BT_INTEGER:
+ return mpz_cmp_si (expr->value.integer, 0) == 0;
+
+ case BT_REAL:
+ return mpfr_zero_p (expr->value.real)
+ && MPFR_SIGN (expr->value.real) >= 0;
+
+ case BT_LOGICAL:
+ return expr->value.logical == 0;
+
+ case BT_COMPLEX:
+ return mpfr_zero_p (mpc_realref (expr->value.complex))
+ && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
+ && mpfr_zero_p (mpc_imagref (expr->value.complex))
+ && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
+
+ default:
+ break;
+ }
+ return false;
+}
+
+
static void
gfc_conv_array_constructor_expr (gfc_se * se, gfc_expr * expr)
{
@@ -3960,6 +3997,9 @@ gfc_conv_initializer (gfc_expr * expr, g
/* Arrays need special handling. */
if (pointer)
return gfc_build_null_descriptor (type);
+ /* Special case assigning an array to zero. */
+ else if (is_zero_initializer_p (expr))
+ return build_constructor (type, NULL);
else
return gfc_conv_array_initializer (type, expr);
}
@@ -5061,41 +5101,6 @@ gfc_trans_arrayfunc_assign (gfc_expr * e
return gfc_finish_block (&se.pre);
}
-/* Determine whether the given EXPR_CONSTANT is a zero initializer. */
-
-static bool
-is_zero_initializer_p (gfc_expr * expr)
-{
- if (expr->expr_type != EXPR_CONSTANT)
- return false;
-
- /* We ignore constants with prescribed memory representations for now. */
- if (expr->representation.string)
- return false;
-
- switch (expr->ts.type)
- {
- case BT_INTEGER:
- return mpz_cmp_si (expr->value.integer, 0) == 0;
-
- case BT_REAL:
- return mpfr_zero_p (expr->value.real)
- && MPFR_SIGN (expr->value.real) >= 0;
-
- case BT_LOGICAL:
- return expr->value.logical == 0;
-
- case BT_COMPLEX:
- return mpfr_zero_p (mpc_realref (expr->value.complex))
- && MPFR_SIGN (mpc_realref (expr->value.complex)) >= 0
- && mpfr_zero_p (mpc_imagref (expr->value.complex))
- && MPFR_SIGN (mpc_imagref (expr->value.complex)) >= 0;
-
- default:
- break;
- }
- return false;
-}
/* Try to efficiently translate array(:) = 0. Return NULL if this
can't be done. */