From: Michael Matz Date: Fri, 15 Apr 2011 21:48:19 +0000 (+0000) Subject: trans-array.c (toplevel): Include gimple.h. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c76f8d52e24c089bbe598e08ef5813e91f02924d;p=gcc.git 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 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 5a8283f1f26..77426165b62 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,16 @@ +2011-04-15 Michael Matz + + * 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 PR fortran/18918 diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in index ac4401dde49..753221d272c 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 73c39669c4c..c2c9d0548f8 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 96beff58215..57f7313f4bd 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{} @gol -fcoarray=@var{} -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{} @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 adc6dce6d1e..3055825047f 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= 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 008346056a7..5e173088d94 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 7c34b9865ea..638234efd69 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); }