On Sat, 9 Apr 2011, Paul Richard Thomas wrote: > I find that both nf.f90 and capacita.f90 segfault in runtime for any > stack size.
Try this patch. I've verified that capacita and nf work with it and -march=native -ffast-math -funroll-loops -fstack-arrays -O3 . In fact all of polyhedron works for me on these flags. (I've set a ulimit -s of 512MB, but I don't know if such a large amount is required). Ciao, Michael. * 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. Index: trans-array.c =================================================================== *** trans-array.c (revision 172206) --- trans-array.c (working copy) *************** along with GCC; see the file COPYING3. *** 81,86 **** --- 81,87 ---- #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" *************** gfc_trans_allocate_array_storage (stmtbl *** 630,647 **** { /* Allocate the temporary. */ onstack = !dynamic && initial == NULL_TREE ! && 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 = 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"); tmp = gfc_build_addr_expr (NULL_TREE, tmp); gfc_conv_descriptor_data_set (pre, desc, tmp); } --- 631,654 ---- { /* Allocate the temporary. */ onstack = !dynamic && initial == NULL_TREE ! && (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"); + 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); } *************** gfc_trans_auto_array_allocation (tree de *** 4744,4749 **** --- 4751,4758 ---- tree tmp; tree size; tree offset; + tree space; + tree inittree; bool onstack; gcc_assert (!(sym->attr.pointer || sym->attr.allocatable)); *************** gfc_trans_auto_array_allocation (tree de *** 4800,4814 **** 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)); ! /* Allocate memory to hold the data. */ ! tmp = gfc_call_malloc (&init, TREE_TYPE (decl), size); ! gfc_add_modify (&init, decl, tmp); /* Set offset of the array. */ if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL) --- 4809,4838 ---- 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 ! 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); ! ! /* 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) *************** gfc_trans_auto_array_allocation (tree de *** 4817,4826 **** /* Automatic arrays should not have initializers. */ gcc_assert (!sym->value); ! /* Free the temporary. */ ! tmp = gfc_call_free (convert (pvoid_type_node, decl)); ! gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp); } --- 4841,4866 ---- /* Automatic arrays should not have initializers. */ gcc_assert (!sym->value); ! inittree = gfc_finish_block (&init); ! ! 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); } Index: Make-lang.in =================================================================== *** Make-lang.in (revision 172206) --- Make-lang.in (working copy) *************** fortran/trans-stmt.o: $(GFORTRAN_TRANS_D *** 353,359 **** 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-intrinsic.o: $(GFORTRAN_TRANS_DEPS) fortran/mathbuiltins.def \ gt-fortran-trans-intrinsic.h fortran/dependency.o: $(GFORTRAN_TRANS_DEPS) fortran/dependency.h --- 353,359 ---- 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) $(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 Index: gfortran.h =================================================================== *** gfortran.h (revision 172206) --- gfortran.h (working copy) *************** typedef struct *** 2220,2225 **** --- 2220,2226 ---- 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; Index: lang.opt =================================================================== *** lang.opt (revision 172206) --- lang.opt (working copy) *************** fmax-stack-var-size= *** 454,459 **** --- 454,463 ---- 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. Index: invoke.texi =================================================================== *** invoke.texi (revision 172206) --- invoke.texi (working copy) *************** and warnings}. *** 167,172 **** --- 167,173 ---- -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 *************** Future versions of GNU Fortran may impro *** 1361,1366 **** --- 1362,1374 ---- 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 Index: options.c =================================================================== *** options.c (revision 172206) --- options.c (working copy) *************** gfc_init_options (unsigned int decoded_o *** 123,128 **** --- 123,129 ---- /* 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; *************** gfc_handle_option (size_t scode, const c *** 783,788 **** --- 784,793 ---- 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;