aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2011-04-15 21:48:19 +0000
committerMichael Matz <matz@gcc.gnu.org>2011-04-15 21:48:19 +0000
commitc76f8d52e24c089bbe598e08ef5813e91f02924d (patch)
treef0232500e3e80f82cf9bf3ed6decd6681d9ccc9a /gcc/fortran
parent5678a5a3bf407b6aa95e827ac6dd1056cdf6b415 (diff)
downloadgcc-c76f8d52e24c089bbe598e08ef5813e91f02924d.zip
gcc-c76f8d52e24c089bbe598e08ef5813e91f02924d.tar.gz
gcc-c76f8d52e24c089bbe598e08ef5813e91f02924d.tar.bz2
trans-array.c (toplevel): Include gimple.h.
* trans-array.c (toplevel): Include gimple.h. (gfc_trans_allocate_array_storage): Check flag_stack_arrays, properly expand variable length arrays. (gfc_trans_auto_array_allocation): If flag_stack_arrays create variable length decls and associate them with their scope. * gfortran.h (gfc_option_t): Add flag_stack_arrays member. * options.c (gfc_init_options): Handle -fstack_arrays option. * lang.opt (fstack-arrays): Add option. * invoke.texi (Code Gen Options): Document it. * Make-lang.in (trans-array.o): Depend on GIMPLE_H. From-SVN: r172524
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog13
-rw-r--r--gcc/fortran/Make-lang.in2
-rw-r--r--gcc/fortran/gfortran.h1
-rw-r--r--gcc/fortran/invoke.texi8
-rw-r--r--gcc/fortran/lang.opt4
-rw-r--r--gcc/fortran/options.c5
-rw-r--r--gcc/fortran/trans-array.c69
7 files changed, 88 insertions, 14 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 5a8283f..7742616 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,16 @@
+2011-04-15 Michael Matz <matz@suse.de>
+
+ * trans-array.c (toplevel): Include gimple.h.
+ (gfc_trans_allocate_array_storage): Check flag_stack_arrays,
+ properly expand variable length arrays.
+ (gfc_trans_auto_array_allocation): If flag_stack_arrays create
+ variable length decls and associate them with their scope.
+ * gfortran.h (gfc_option_t): Add flag_stack_arrays member.
+ * options.c (gfc_init_options): Handle -fstack_arrays option.
+ * lang.opt (fstack-arrays): Add option.
+ * invoke.texi (Code Gen Options): Document it.
+ * Make-lang.in (trans-array.o): Depend on GIMPLE_H.
+
2011-04-15 Tobias Burnus <burnus@net-b.de>
PR fortran/18918
diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in
index ac4401d..753221d 100644
--- a/gcc/fortran/Make-lang.in
+++ b/gcc/fortran/Make-lang.in
@@ -353,7 +353,7 @@ fortran/trans-stmt.o: $(GFORTRAN_TRANS_DEPS) fortran/dependency.h
fortran/trans-openmp.o: $(GFORTRAN_TRANS_DEPS)
fortran/trans-io.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-io.h \
fortran/ioparm.def
-fortran/trans-array.o: $(GFORTRAN_TRANS_DEPS)
+fortran/trans-array.o: $(GFORTRAN_TRANS_DEPS) $(GIMPLE_H)
fortran/trans-intrinsic.o: $(GFORTRAN_TRANS_DEPS) fortran/mathbuiltins.def \
gt-fortran-trans-intrinsic.h
fortran/dependency.o: $(GFORTRAN_TRANS_DEPS) fortran/dependency.h
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 73c3966..c2c9d05 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -2221,6 +2221,7 @@ typedef struct
int flag_d_lines;
int gfc_flag_openmp;
int flag_sign_zero;
+ int flag_stack_arrays;
int flag_module_private;
int flag_recursive;
int flag_init_local_zero;
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 96beff5..57f7313 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -167,6 +167,7 @@ and warnings}.
-fbounds-check -fcheck-array-temporaries -fmax-array-constructor =@var{n} @gol
-fcheck=@var{<all|array-temps|bounds|do|mem|pointer|recursion>} @gol
-fcoarray=@var{<none|single|lib>} -fmax-stack-var-size=@var{n} @gol
+-fstack-arrays @gol
-fpack-derived -frepack-arrays -fshort-enums -fexternal-blas @gol
-fblas-matmul-limit=@var{n} -frecursive -finit-local-zero @gol
-finit-integer=@var{n} -finit-real=@var{<zero|inf|-inf|nan|snan>} @gol
@@ -1370,6 +1371,13 @@ Future versions of GNU Fortran may improve this behavior.
The default value for @var{n} is 32768.
+@item -fstack-arrays
+@opindex @code{fstack-arrays}
+Adding this option will make the fortran compiler put all local arrays,
+even those of unknown size onto stack memory. If your program uses very
+large local arrays it's possible that you'll have to extend your runtime
+limits for stack memory on some operating systems.
+
@item -fpack-derived
@opindex @code{fpack-derived}
@cindex structure packing
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index adc6dce..3055825 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -462,6 +462,10 @@ fmax-stack-var-size=
Fortran RejectNegative Joined UInteger
-fmax-stack-var-size=<n> Size in bytes of the largest array that will be put on the stack
+fstack-arrays
+Fortran
+Put all local arrays on stack.
+
fmodule-private
Fortran
Set default accessibility of module entities to PRIVATE.
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 0083460..5e17308 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -124,6 +124,7 @@ gfc_init_options (unsigned int decoded_options_count,
/* 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_stack_arrays = 0;
gfc_option.flag_range_check = 1;
gfc_option.flag_pack_derived = 0;
@@ -795,6 +796,10 @@ gfc_handle_option (size_t scode, const char *arg, int value,
gfc_option.flag_max_stack_var_size = value;
break;
+ case OPT_fstack_arrays:
+ gfc_option.flag_stack_arrays = value;
+ break;
+
case OPT_fmodule_private:
gfc_option.flag_module_private = value;
break;
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 7c34b98..638234e 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -81,6 +81,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
+#include "gimple.h"
#include "diagnostic-core.h" /* For internal_error/fatal_error. */
#include "flags.h"
#include "gfortran.h"
@@ -630,18 +631,27 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
{
/* Allocate the temporary. */
onstack = !dynamic && initial == NULL_TREE
- && gfc_can_put_var_on_stack (size);
+ && (gfc_option.flag_stack_arrays
+ || gfc_can_put_var_on_stack (size));
if (onstack)
{
/* Make a temporary variable to hold the data. */
tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (nelem),
nelem, gfc_index_one_node);
+ tmp = gfc_evaluate_now (tmp, pre);
tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
tmp);
tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
tmp);
tmp = gfc_create_var (tmp, "A");
+ /* If we're here only because of -fstack-arrays we have to
+ emit a DECL_EXPR to make the gimplifier emit alloca calls. */
+ if (!gfc_can_put_var_on_stack (size))
+ gfc_add_expr_to_block (pre,
+ fold_build1_loc (input_location,
+ DECL_EXPR, TREE_TYPE (tmp),
+ tmp));
tmp = gfc_build_addr_expr (NULL_TREE, tmp);
gfc_conv_descriptor_data_set (pre, desc, tmp);
}
@@ -4759,9 +4769,11 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
{
stmtblock_t init;
tree type;
- tree tmp;
+ tree tmp = NULL_TREE;
tree size;
tree offset;
+ tree space;
+ tree inittree;
bool onstack;
gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
@@ -4818,15 +4830,30 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
return;
}
- /* The size is the number of elements in the array, so multiply by the
- size of an element to get the total size. */
- tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
- size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
- size, fold_convert (gfc_array_index_type, tmp));
+ if (gfc_option.flag_stack_arrays)
+ {
+ gcc_assert (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE);
+ space = build_decl (sym->declared_at.lb->location,
+ VAR_DECL, create_tmp_var_name ("A"),
+ TREE_TYPE (TREE_TYPE (decl)));
+ gfc_trans_vla_type_sizes (sym, &init);
+ }
+ else
+ {
+ /* The size is the number of elements in the array, so multiply by the
+ size of an element to get the total size. */
+ tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
+ size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
+ size, fold_convert (gfc_array_index_type, tmp));
- /* Allocate memory to hold the data. */
- tmp = gfc_call_malloc (&init, TREE_TYPE (decl), size);
- gfc_add_modify (&init, decl, tmp);
+ /* Allocate memory to hold the data. */
+ tmp = gfc_call_malloc (&init, TREE_TYPE (decl), size);
+ gfc_add_modify (&init, decl, tmp);
+
+ /* Free the temporary. */
+ tmp = gfc_call_free (convert (pvoid_type_node, decl));
+ space = NULL_TREE;
+ }
/* Set offset of the array. */
if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
@@ -4835,10 +4862,26 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
/* Automatic arrays should not have initializers. */
gcc_assert (!sym->value);
- /* Free the temporary. */
- tmp = gfc_call_free (convert (pvoid_type_node, decl));
+ inittree = gfc_finish_block (&init);
- gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
+ if (space)
+ {
+ tree addr;
+ pushdecl (space);
+
+ /* Don't create new scope, emit the DECL_EXPR in exactly the scope
+ where also space is located. */
+ gfc_init_block (&init);
+ tmp = fold_build1_loc (input_location, DECL_EXPR,
+ TREE_TYPE (space), space);
+ gfc_add_expr_to_block (&init, tmp);
+ addr = fold_build1_loc (sym->declared_at.lb->location,
+ ADDR_EXPR, TREE_TYPE (decl), space);
+ gfc_add_modify (&init, decl, addr);
+ gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
+ tmp = NULL_TREE;
+ }
+ gfc_add_init_cleanup (block, inittree, tmp);
}