diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 81d7bddd56d..903b713054b 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,14 @@ +2007-08-26 Asher Langton + Tobias Burnus + + * gfortran.h (gfc_option_t): Add flag_recursive. + * lang.opt: Add -frecursive option and update -fopenmp. + * invoke.texi (-frecursive): Document new option. + (-fopenmp,-fno-automatic,-fmax-stack-var-size): Update. + * options.c (gfc_init_options, gfc_post_options, + gfc_handle_option): Add -frecursive and modify -fopenmp. + (gfc_post_options): Add warning for conflicting flags. + 2007-08-26 Tobias Burnus PR fortran/31298 diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 11d7adce8f7..383270e603a 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1863,6 +1863,7 @@ typedef struct int flag_openmp; int flag_sign_zero; int flag_module_private; + int flag_recursive; int fpe; diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index c68a2613960..e58cb8cbee7 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -156,7 +156,7 @@ and warnings}. -fsecond-underscore @gol -fbounds-check -fmax-stack-var-size=@var{n} @gol -fpack-derived -frepack-arrays -fshort-enums -fexternal-blas @gol --fblas-matmul-limit=@var{n}} +-fblas-matmul-limit=@var{n} -frecursive} @end table @menu @@ -296,7 +296,7 @@ and @code{c$omp}, @code{*$omp} and @code{!$omp} directives in fixed form, @code{!$} conditional compilation sentinels in free form and @code{c$}, @code{*$} and @code{!$} sentinels in fixed form, and when linking arranges for the OpenMP runtime library to be linked -in. +in. The option @option{-fopenmp} implies @option{-frecursive}. @item -frange-check @opindex @code{frange-check} @@ -710,10 +710,13 @@ it. @opindex @code{fno-automatic} @cindex @code{SAVE} statement @cindex statement, @code{SAVE} -Treat each program unit as if the @code{SAVE} statement was specified for -every local variable and array referenced in it. Does not affect common -blocks. (Some Fortran compilers provide this option under the name -@option{-static}.) +Treat each program unit (except those marked as RECURSIVE) as if the +@code{SAVE} statement were specified for every local variable and array +referenced in it. Does not affect common blocks. (Some Fortran compilers +provide this option under the name @option{-static} or @option{-save}.) +The default, which is @option{-fautomatic}, uses the stack for local +variables smaller than the value given by @option{-fmax-stack-var-size}. +Use the option @option{-frecursive} to use no static memory. @item -ff2c @opindex ff2c @@ -865,7 +868,10 @@ substring references. @item -fmax-stack-var-size=@var{n} @opindex @code{fmax-stack-var-size} This option specifies the size in bytes of the largest array that will be put -on the stack. +on the stack; if the size is exceeded static memory is used (except in +procedures marked as RECURSIVE). Use the option @option{-frecursive} to +allow for recursive procedures which do not have a RECURSIVE attribute or +for parallel programs. Use @option{-fno-automatic} to never use the stack. This option currently only affects local arrays declared with constant bounds, and may not apply to all character variables. @@ -919,6 +925,12 @@ geometric mean of the dimensions of the argument and result matrices. The default value for @var{n} is 30. +@item -frecursive +@opindex @code{frecursive} +Allow indirect recursion by forcing all local arrays to be allocated +on the stack. This flag cannot be used together with +@option{-fmax-stack-var-size=} or @option{-fno-automatic}. + @end table @xref{Code Gen Options,,Options for Code Generation Conventions, diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index 3072051a1f4..558cf657aac 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -218,7 +218,7 @@ Set default accessibility of module entities to PRIVATE. fopenmp Fortran -Enable OpenMP +Enable OpenMP (also sets frecursive) fpack-derived Fortran @@ -240,6 +240,10 @@ frecord-marker=8 Fortran RejectNegative Use an 8-byte record marker for unformatted files +frecursive +Fortran +Allocate local variables on the stack to allow indirect recursion + frepack-arrays Fortran Copy array sections into a contiguous block on procedure entry diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c index 0bea67d7eea..3ab736236be 100644 --- a/gcc/fortran/options.c +++ b/gcc/fortran/options.c @@ -86,7 +86,10 @@ gfc_init_options (unsigned int argc ATTRIBUTE_UNUSED, gfc_option.flag_f2c = 0; gfc_option.flag_second_underscore = -1; gfc_option.flag_implicit_none = 0; - gfc_option.flag_max_stack_var_size = 32768; + + /* Default value of flag_max_stack_var_size is set in gfc_post_options. */ + gfc_option.flag_max_stack_var_size = -2; + gfc_option.flag_range_check = 1; gfc_option.flag_pack_derived = 0; gfc_option.flag_repack_arrays = 0; @@ -103,6 +106,7 @@ gfc_init_options (unsigned int argc ATTRIBUTE_UNUSED, gfc_option.flag_d_lines = -1; gfc_option.flag_openmp = 0; gfc_option.flag_sign_zero = 1; + gfc_option.flag_recursive = 0; gfc_option.fpe = 0; @@ -290,6 +294,37 @@ gfc_post_options (const char **pfilename) if (gfc_option.flag_second_underscore == -1) gfc_option.flag_second_underscore = gfc_option.flag_f2c; + if (!gfc_option.flag_automatic && gfc_option.flag_max_stack_var_size != -2 + && gfc_option.flag_max_stack_var_size != 0) + gfc_warning_now ("Flag -fno-automatic overwrites -fmax-stack-var-size=%d", + gfc_option.flag_max_stack_var_size); + else if (!gfc_option.flag_automatic && gfc_option.flag_recursive) + gfc_warning_now ("Flag -fno-automatic overwrites -frecursive"); + else if (!gfc_option.flag_automatic && gfc_option.flag_openmp) + gfc_warning_now ("Flag -fno-automatic overwrites -frecursive implied by " + "-fopenmp"); + else if (gfc_option.flag_max_stack_var_size != -2 + && gfc_option.flag_recursive) + gfc_warning_now ("Flag -frecursive overwrites -fmax-stack-var-size=%d", + gfc_option.flag_max_stack_var_size); + else if (gfc_option.flag_max_stack_var_size != -2 + && gfc_option.flag_openmp) + gfc_warning_now ("Flag -fmax-stack-var-size=%d overwrites -frecursive " + "implied by -fopenmp", + gfc_option.flag_max_stack_var_size); + + /* Implied -frecursive; implemented as -fmax-stack-var-size=-1. */ + if (gfc_option.flag_max_stack_var_size == -2 && gfc_option.flag_openmp) + gfc_option.flag_max_stack_var_size = -1; + + /* Set default. */ + if (gfc_option.flag_max_stack_var_size == -2) + gfc_option.flag_max_stack_var_size = 32768; + + /* Implement -frecursive as -fmax-stack-var-size=-1. */ + if (gfc_option.flag_recursive) + gfc_option.flag_max_stack_var_size = -1; + /* Implement -fno-automatic as -fmax-stack-var-size=0. */ if (!gfc_option.flag_automatic) gfc_option.flag_max_stack_var_size = 0; @@ -698,6 +733,11 @@ gfc_handle_option (size_t scode, const char *arg, int value) MAX_SUBRECORD_LENGTH); gfc_option.max_subrecord_length = value; + break; + + case OPT_frecursive: + gfc_option.flag_recursive = 1; + break; } return result; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 43875beb80f..d0be7eeb4e5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-08-26 Asher Langton + + * gfortran.dg/recursive_stack.f90: New. + * gfortran.dg/openmp_stack.f90: New. + 2007-08-26 Tobias Burnus PR fortran/31298 diff --git a/gcc/testsuite/gfortran.dg/openmp_stack.f90 b/gcc/testsuite/gfortran.dg/openmp_stack.f90 new file mode 100644 index 00000000000..97dd9156cf2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/openmp_stack.f90 @@ -0,0 +1,22 @@ +! { dg-do run} +! { dg-options "-fopenmp" } +program openmp_stack + implicit none + integer id + integer ilocs(2) + integer omp_get_thread_num, foo + call omp_set_num_threads (2) +!$omp parallel private (id) + id = omp_get_thread_num() + 1 + ilocs(id) = foo() +!$omp end parallel + ! Check that the two threads are not sharing a location for + ! the array x in foo() + if (ilocs(1) .eq. ilocs(2)) call abort +end program openmp_stack + +integer function foo () + implicit none + real x(100,100) + foo = loc(x) +end function foo diff --git a/gcc/testsuite/gfortran.dg/recursive_stack.f90 b/gcc/testsuite/gfortran.dg/recursive_stack.f90 new file mode 100644 index 00000000000..7dbe9fcd740 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/recursive_stack.f90 @@ -0,0 +1,21 @@ +! { dg-do run} +! { dg-options "-frecursive" } +program recursive_stack + call foo (.true.) +end program recursive_stack + +subroutine foo (recurse) + logical recurse + integer iarray(100,100) + if (recurse) then + iarray(49,49) = 17 + call bar + if (iarray(49,49) .ne. 17) call abort + else + iarray(49,49) = 21 + end if +end subroutine foo + +subroutine bar + call foo (.false.) +end subroutine bar