Commit c76f8d52 by Michael Matz Committed by Michael Matz

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
parent 5678a5a3
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> 2011-04-15 Tobias Burnus <burnus@net-b.de>
PR fortran/18918 PR fortran/18918
......
...@@ -353,7 +353,7 @@ fortran/trans-stmt.o: $(GFORTRAN_TRANS_DEPS) fortran/dependency.h ...@@ -353,7 +353,7 @@ fortran/trans-stmt.o: $(GFORTRAN_TRANS_DEPS) fortran/dependency.h
fortran/trans-openmp.o: $(GFORTRAN_TRANS_DEPS) fortran/trans-openmp.o: $(GFORTRAN_TRANS_DEPS)
fortran/trans-io.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-io.h \ fortran/trans-io.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-io.h \
fortran/ioparm.def 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 \ fortran/trans-intrinsic.o: $(GFORTRAN_TRANS_DEPS) fortran/mathbuiltins.def \
gt-fortran-trans-intrinsic.h gt-fortran-trans-intrinsic.h
fortran/dependency.o: $(GFORTRAN_TRANS_DEPS) fortran/dependency.h fortran/dependency.o: $(GFORTRAN_TRANS_DEPS) fortran/dependency.h
......
...@@ -2221,6 +2221,7 @@ typedef struct ...@@ -2221,6 +2221,7 @@ typedef struct
int flag_d_lines; int flag_d_lines;
int gfc_flag_openmp; int gfc_flag_openmp;
int flag_sign_zero; int flag_sign_zero;
int flag_stack_arrays;
int flag_module_private; int flag_module_private;
int flag_recursive; int flag_recursive;
int flag_init_local_zero; int flag_init_local_zero;
......
...@@ -167,6 +167,7 @@ and warnings}. ...@@ -167,6 +167,7 @@ and warnings}.
-fbounds-check -fcheck-array-temporaries -fmax-array-constructor =@var{n} @gol -fbounds-check -fcheck-array-temporaries -fmax-array-constructor =@var{n} @gol
-fcheck=@var{<all|array-temps|bounds|do|mem|pointer|recursion>} @gol -fcheck=@var{<all|array-temps|bounds|do|mem|pointer|recursion>} @gol
-fcoarray=@var{<none|single|lib>} -fmax-stack-var-size=@var{n} @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 -fpack-derived -frepack-arrays -fshort-enums -fexternal-blas @gol
-fblas-matmul-limit=@var{n} -frecursive -finit-local-zero @gol -fblas-matmul-limit=@var{n} -frecursive -finit-local-zero @gol
-finit-integer=@var{n} -finit-real=@var{<zero|inf|-inf|nan|snan>} @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. ...@@ -1370,6 +1371,13 @@ Future versions of GNU Fortran may improve this behavior.
The default value for @var{n} is 32768. 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 @item -fpack-derived
@opindex @code{fpack-derived} @opindex @code{fpack-derived}
@cindex structure packing @cindex structure packing
......
...@@ -462,6 +462,10 @@ fmax-stack-var-size= ...@@ -462,6 +462,10 @@ fmax-stack-var-size=
Fortran RejectNegative Joined UInteger Fortran RejectNegative Joined UInteger
-fmax-stack-var-size=<n> Size in bytes of the largest array that will be put on the stack -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 fmodule-private
Fortran Fortran
Set default accessibility of module entities to PRIVATE. Set default accessibility of module entities to PRIVATE.
......
...@@ -124,6 +124,7 @@ gfc_init_options (unsigned int decoded_options_count, ...@@ -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. */ /* 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_max_stack_var_size = -2;
gfc_option.flag_stack_arrays = 0;
gfc_option.flag_range_check = 1; gfc_option.flag_range_check = 1;
gfc_option.flag_pack_derived = 0; gfc_option.flag_pack_derived = 0;
...@@ -795,6 +796,10 @@ gfc_handle_option (size_t scode, const char *arg, int value, ...@@ -795,6 +796,10 @@ gfc_handle_option (size_t scode, const char *arg, int value,
gfc_option.flag_max_stack_var_size = value; gfc_option.flag_max_stack_var_size = value;
break; break;
case OPT_fstack_arrays:
gfc_option.flag_stack_arrays = value;
break;
case OPT_fmodule_private: case OPT_fmodule_private:
gfc_option.flag_module_private = value; gfc_option.flag_module_private = value;
break; break;
......
...@@ -81,6 +81,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -81,6 +81,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h" #include "system.h"
#include "coretypes.h" #include "coretypes.h"
#include "tree.h" #include "tree.h"
#include "gimple.h"
#include "diagnostic-core.h" /* For internal_error/fatal_error. */ #include "diagnostic-core.h" /* For internal_error/fatal_error. */
#include "flags.h" #include "flags.h"
#include "gfortran.h" #include "gfortran.h"
...@@ -630,18 +631,27 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post, ...@@ -630,18 +631,27 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
{ {
/* Allocate the temporary. */ /* Allocate the temporary. */
onstack = !dynamic && initial == NULL_TREE 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) if (onstack)
{ {
/* Make a temporary variable to hold the data. */ /* Make a temporary variable to hold the data. */
tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (nelem), tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (nelem),
nelem, gfc_index_one_node); nelem, gfc_index_one_node);
tmp = gfc_evaluate_now (tmp, pre);
tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
tmp); tmp);
tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)), tmp = build_array_type (gfc_get_element_type (TREE_TYPE (desc)),
tmp); tmp);
tmp = gfc_create_var (tmp, "A"); 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); tmp = gfc_build_addr_expr (NULL_TREE, tmp);
gfc_conv_descriptor_data_set (pre, desc, tmp); gfc_conv_descriptor_data_set (pre, desc, tmp);
} }
...@@ -4759,9 +4769,11 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, ...@@ -4759,9 +4769,11 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
{ {
stmtblock_t init; stmtblock_t init;
tree type; tree type;
tree tmp; tree tmp = NULL_TREE;
tree size; tree size;
tree offset; tree offset;
tree space;
tree inittree;
bool onstack; bool onstack;
gcc_assert (!(sym->attr.pointer || sym->attr.allocatable)); gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
...@@ -4818,6 +4830,16 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, ...@@ -4818,6 +4830,16 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
return; return;
} }
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 /* The size is the number of elements in the array, so multiply by the
size of an element to get the total size. */ size of an element to get the total size. */
tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type)); tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
...@@ -4828,6 +4850,11 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, ...@@ -4828,6 +4850,11 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
tmp = gfc_call_malloc (&init, TREE_TYPE (decl), size); tmp = gfc_call_malloc (&init, TREE_TYPE (decl), size);
gfc_add_modify (&init, decl, tmp); 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. */ /* Set offset of the array. */
if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL) if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset); gfc_add_modify (&init, GFC_TYPE_ARRAY_OFFSET (type), offset);
...@@ -4835,10 +4862,26 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, ...@@ -4835,10 +4862,26 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym,
/* Automatic arrays should not have initializers. */ /* Automatic arrays should not have initializers. */
gcc_assert (!sym->value); gcc_assert (!sym->value);
/* Free the temporary. */ inittree = gfc_finish_block (&init);
tmp = gfc_call_free (convert (pvoid_type_node, decl));
if (space)
{
tree addr;
pushdecl (space);
gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp); /* 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);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment