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
This commit is contained in:
Michael Matz 2011-04-15 21:48:19 +00:00 committed by Michael Matz
parent 5678a5a3bf
commit c76f8d52e2
7 changed files with 88 additions and 14 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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);
}