diff options
-rw-r--r-- | gcc/ChangeLog | 36 | ||||
-rw-r--r-- | gcc/Makefile.in | 4 | ||||
-rw-r--r-- | gcc/ada/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 10 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils2.c | 7 | ||||
-rw-r--r-- | gcc/calls.c | 8 | ||||
-rw-r--r-- | gcc/common.opt | 10 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 30 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 49 | ||||
-rw-r--r-- | gcc/explow.c | 12 | ||||
-rw-r--r-- | gcc/expr.h | 25 | ||||
-rw-r--r-- | gcc/flags.h | 21 | ||||
-rw-r--r-- | gcc/function.c | 15 | ||||
-rw-r--r-- | gcc/gimplify.c | 6 | ||||
-rw-r--r-- | gcc/opts.c | 32 | ||||
-rw-r--r-- | gcc/reload1.c | 6 | ||||
-rw-r--r-- | gcc/stmt.c | 46 | ||||
-rw-r--r-- | gcc/toplev.c | 3 |
18 files changed, 233 insertions, 95 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f7218cdd088..faa92264ee7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,39 @@ +2008-08-16 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/20548 + * common.opt (-fstack-check): Do not declare the variable here. + (-fstack-check=): New option variant. + * doc/invoke.texi (Code Gen Options): Document it. + * expr.h (STACK_OLD_CHECK_PROTECT): New macro. + (STACK_CHECK_PROTECT): Bump to 3 pages if DWARF-2 EH is used. + (STACK_CHECK_STATIC_BUILTIN): New macro. + * doc/tm.texi (Stack Checking): Document STACK_CHECK_STATIC_BUILTIN. + * opts.c: Include expr.h. + (common_handle_option) <OPT_fold_stack_check_>: New case. + <OPT_fstack_check>: Likewise. + * calls.c (initialize_argument_information): Use TYPE_SIZE_UNIT + consistently in the test for variable-sized types. Adjust for + new behaviour of flag_stack_check. + * explow.c: Include except.h. + (allocate_dynamic_stack_space): Do not take into account + STACK_CHECK_MAX_FRAME_SIZE for static builtin stack checking. + * function.c (gimplify_parameters): Use DECL_SIZE_UNIT in the test + for variable-sized parameters. Treat all parameters whose size is + greater than STACK_CHECK_MAX_VAR_SIZE as variable-sized if generic + stack checking is enabled. + * gimplify.c (gimplify_decl_expr): Treat non-static objects whose + size is greater than STACK_CHECK_MAX_VAR_SIZE as variable-sized + if generic stack checking is enabled. + (expand_function_end): Adjust for new behaviour of flag_stack_check. + * reload1.c (reload): Likewise. + * stmt.c (expand_decl): Assert that all automatic variables have + fixed size at this point and remove dead code. + * flags.h (stack_check_type): New enumeration type. + (flag_stack_check): Declare. + * toplev.c (flag_stack_check): New global variable. + * Makefile.in (opts.o): Add dependency on EXPR_H. + (explow.o): Add dependency on except.h. + 2008-08-16 Andy Hutchinson <hutchinsonandy@aim.com> * config/avr/avr.c (avr_override_options): Reduce value of diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 8970d1bf6a3..3c6318ee694 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2392,7 +2392,7 @@ diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) version.h $(TM_P_H) $(FLAGS_H) $(INPUT_H) $(TOPLEV_H) intl.h \ $(DIAGNOSTIC_H) langhooks.h $(LANGHOOKS_DEF_H) diagnostic.def opts.h opts.o : opts.c opts.h options.h $(TOPLEV_H) $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(RTL_H) \ + coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(EXPR_H) $(RTL_H) \ output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \ $(FLAGS_H) $(PARAMS_H) tree-pass.h $(DBGCNT_H) debug.h varray.h opts-common.o : opts-common.c opts.h $(CONFIG_H) $(SYSTEM_H) \ @@ -2495,7 +2495,7 @@ expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_ $(TOPLEV_H) $(TM_P_H) langhooks.h $(DF_H) $(TARGET_H) explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ $(FLAGS_H) hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \ - $(TOPLEV_H) $(FUNCTION_H) $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h \ + $(TOPLEV_H) except.h $(FUNCTION_H) $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h \ $(TARGET_H) output.h optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h \ diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 39f8cd17ae9..14abbe489ac 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,11 @@ +2008-08-16 Eric Botcazou <ebotcazou@adacore.com> + + PR ada/20548 + * gcc-interface/decl.c (gnat_to_gnu_entity): Use DECL_SIZE_UNIT in the + setjmp test consistently. Adjust for new behaviour of flag_stack_check. + * gcc-interface/utils2.c (build_call_alloc_dealloc): Remove redundant + test of flag_stack_check. Adjust for new behaviour of flag_stack_check. + 2008-08-13 Samuel Tardieu <sam@rfc1149.net> PR ada/36777 diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index a136f96bcc8..65dd02e7834 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -1303,12 +1303,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) } } - if (definition && DECL_SIZE (gnu_decl) + if (definition && DECL_SIZE_UNIT (gnu_decl) && get_block_jmpbuf_decl () - && (TREE_CODE (DECL_SIZE (gnu_decl)) != INTEGER_CST - || (flag_stack_check && !STACK_CHECK_BUILTIN - && 0 < compare_tree_int (DECL_SIZE_UNIT (gnu_decl), - STACK_CHECK_MAX_VAR_SIZE)))) + && (TREE_CODE (DECL_SIZE_UNIT (gnu_decl)) != INTEGER_CST + || (flag_stack_check == GENERIC_STACK_CHECK + && compare_tree_int (DECL_SIZE_UNIT (gnu_decl), + STACK_CHECK_MAX_VAR_SIZE) > 0))) add_stmt_with_node (build_call_1_expr (update_setjmp_buf_decl, build_unary_op (ADDR_EXPR, NULL_TREE, diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index 0462426251f..5077e640121 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -1920,11 +1920,11 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, unsigned align, /* ??? For now, disable variable-sized allocators in the stack since we can't yet gimplify an ALLOCATE_EXPR. */ else if (gnat_pool == -1 - && TREE_CODE (gnu_size) == INTEGER_CST && !flag_stack_check) + && TREE_CODE (gnu_size) == INTEGER_CST + && flag_stack_check != GENERIC_STACK_CHECK) { /* If the size is a constant, we can put it in the fixed portion of the stack frame to avoid the need to adjust the stack pointer. */ - if (TREE_CODE (gnu_size) == INTEGER_CST && !flag_stack_check) { tree gnu_range = build_range_type (NULL_TREE, size_one_node, gnu_size); @@ -1937,9 +1937,8 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, unsigned align, return convert (ptr_void_type_node, build_unary_op (ADDR_EXPR, NULL_TREE, gnu_decl)); } - else - gcc_unreachable (); #if 0 + else return build2 (ALLOCATE_EXPR, ptr_void_type_node, gnu_size, gnu_align); #endif } diff --git a/gcc/calls.c b/gcc/calls.c index 27aaaee6eff..3f322445560 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1069,10 +1069,10 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED, rtx copy; if (!COMPLETE_TYPE_P (type) - || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST - || (flag_stack_check && ! STACK_CHECK_BUILTIN - && (0 < compare_tree_int (TYPE_SIZE_UNIT (type), - STACK_CHECK_MAX_VAR_SIZE)))) + || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST + || (flag_stack_check == GENERIC_STACK_CHECK + && compare_tree_int (TYPE_SIZE_UNIT (type), + STACK_CHECK_MAX_VAR_SIZE) > 0)) { /* This is a variable-sized object. Make space on the stack for it. */ diff --git a/gcc/common.opt b/gcc/common.opt index 9b1972b8c4a..bad670903e3 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -992,11 +992,13 @@ fvariable-expansion-in-unroller Common Report Var(flag_variable_expansion_in_unroller) Optimization Apply variable expansion when loops are unrolled -; Emit code to probe the stack, to help detect stack overflow; also -; may cause large objects to be allocated dynamically. +fstack-check= +Common Report RejectNegative Joined +-fstack-check=[no|generic|specific] Insert stack checking code into the program + fstack-check -Common Report Var(flag_stack_check) -Insert stack checking code into the program +Common Report +Insert stack checking code into the program. Same as -fstack-check=specific fstack-limit Common diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 56a0bdadc55..40c3df16594 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -15207,8 +15207,34 @@ a single-threaded environment since stack overflow is automatically detected on nearly all systems if there is only one stack. Note that this switch does not actually cause checking to be done; the -operating system must do that. The switch causes generation of code -to ensure that the operating system sees the stack being extended. +operating system or the language runtime must do that. The switch causes +generation of code to ensure that they see the stack being extended. + +You can additionally specify a string parameter: @code{no} means no +checking, @code{generic} means force the use of old-style checking, +@code{specific} means use the best checking method and is equivalent +to bare @option{-fstack-check}. + +Old-style checking is a generic mechanism that requires no specific +target support in the compiler but comes with the following drawbacks: + +@enumerate +@item +Modified allocation strategy for large objects: they will always be +allocated dynamically if their size exceeds a fixed threshold. + +@item +Fixed limit on the size of the static frame of functions: when it is +topped by a particular function, stack checking is not reliable and +a warning is issued by the compiler. + +@item +Inefficiency: because of both the modified allocation strategy and the +generic implementation, the performances of the code are hampered. +@end enumerate + +Note that old-style stack checking is also the fallback method for +@code{specific} if no target support has been added in the compiler. @item -fstack-limit-register=@var{reg} @itemx -fstack-limit-symbol=@var{sym} diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 5decc331bd4..9b4a921883f 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3376,38 +3376,49 @@ linkage is necessary. The default is @code{0}. @node Stack Checking @subsection Specifying How Stack Checking is Done -GCC will check that stack references are within the boundaries of -the stack, if the @option{-fstack-check} is specified, in one of three ways: +GCC will check that stack references are within the boundaries of the +stack, if the option @option{-fstack-check} is specified, in one of +three ways: @enumerate @item If the value of the @code{STACK_CHECK_BUILTIN} macro is nonzero, GCC -will assume that you have arranged for stack checking to be done at -appropriate places in the configuration files, e.g., in -@code{TARGET_ASM_FUNCTION_PROLOGUE}. GCC will do not other special -processing. +will assume that you have arranged for full stack checking to be done +at appropriate places in the configuration files. GCC will not do +other special processing. @item -If @code{STACK_CHECK_BUILTIN} is zero and you defined a named pattern -called @code{check_stack} in your @file{md} file, GCC will call that -pattern with one argument which is the address to compare the stack -value against. You must arrange for this pattern to report an error if -the stack pointer is out of range. +If @code{STACK_CHECK_BUILTIN} is zero and the value of the +@code{STACK_CHECK_STATIC_BUILTIN} macro is nonzero, GCC will assume +that you have arranged for static stack checking (checking of the +static stack frame of functions) to be done at appropriate places +in the configuration files. GCC will only emit code to do dynamic +stack checking (checking on dynamic stack allocations) using the third +approach below. @item If neither of the above are true, GCC will generate code to periodically ``probe'' the stack pointer using the values of the macros defined below. @end enumerate -Normally, you will use the default values of these macros, so GCC -will use the third approach. +If neither STACK_CHECK_BUILTIN nor STACK_CHECK_STATIC_BUILTIN is defined, +GCC will change its allocation strategy for large objects if the option +@option{-fstack-check} is specified: they will always be allocated +dynamically if their size exceeds @code{STACK_CHECK_MAX_VAR_SIZE} bytes. @defmac STACK_CHECK_BUILTIN A nonzero value if stack checking is done by the configuration files in a machine-dependent manner. You should define this macro if stack checking -is require by the ABI of your machine or if you would like to have to stack -checking in some more efficient way than GCC's portable approach. -The default value of this macro is zero. +is require by the ABI of your machine or if you would like to do stack +checking in some more efficient way than the generic approach. The default +value of this macro is zero. +@end defmac + +@defmac STACK_CHECK_STATIC_BUILTIN +A nonzero value if static stack checking is done by the configuration files +in a machine-dependent manner. You should define this macro if you would +like to do static stack checking in some more efficient way than the generic +approach. The default value of this macro is zero. @end defmac @defmac STACK_CHECK_PROBE_INTERVAL @@ -3418,7 +3429,7 @@ default value of 4096 is suitable for most systems. @end defmac @defmac STACK_CHECK_PROBE_LOAD -A integer which is nonzero if GCC should perform the stack probe +An integer which is nonzero if GCC should perform the stack probe as a load instruction and zero if GCC should use a store instruction. The default is zero, which is the most efficient choice on most systems. @end defmac @@ -3429,6 +3440,10 @@ for languages where such a recovery is supported. The default value of 75 words should be adequate for most machines. @end defmac +The following macros are relevant only if neither STACK_CHECK_BUILTIN +nor STACK_CHECK_STATIC_BUILTIN is defined; you can omit them altogether +in the opposite case. + @defmac STACK_CHECK_MAX_FRAME_SIZE The maximum size of a stack frame, in bytes. GCC will generate probe instructions in non-leaf functions to ensure at least this many bytes of diff --git a/gcc/explow.c b/gcc/explow.c index 0c941d5b337..a1f76506023 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "tm_p.h" #include "flags.h" +#include "except.h" #include "function.h" #include "expr.h" #include "optabs.h" @@ -1190,10 +1191,13 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align) gcc_assert (!(stack_pointer_delta % (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT))); - /* If needed, check that we have the required amount of stack. Take into - account what has already been checked. */ - if (flag_stack_check && ! STACK_CHECK_BUILTIN) - probe_stack_range (STACK_CHECK_MAX_FRAME_SIZE + STACK_CHECK_PROTECT, size); + /* If needed, check that we have the required amount of stack. + Take into account what has already been checked. */ + if (flag_stack_check == GENERIC_STACK_CHECK) + probe_stack_range (STACK_OLD_CHECK_PROTECT + STACK_CHECK_MAX_FRAME_SIZE, + size); + else if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK) + probe_stack_range (STACK_CHECK_PROTECT, size); /* Don't use a TARGET that isn't a pseudo or is the wrong mode. */ if (target == 0 || !REG_P (target) diff --git a/gcc/expr.h b/gcc/expr.h index 39a51fcfe13..29b1f3e9312 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -208,10 +208,16 @@ do { \ /* Provide default values for the macros controlling stack checking. */ +/* The default is neither full builtin stack checking... */ #ifndef STACK_CHECK_BUILTIN #define STACK_CHECK_BUILTIN 0 #endif +/* ...nor static builtin stack checking. */ +#ifndef STACK_CHECK_STATIC_BUILTIN +#define STACK_CHECK_STATIC_BUILTIN 0 +#endif + /* The default interval is one page. */ #ifndef STACK_CHECK_PROBE_INTERVAL #define STACK_CHECK_PROBE_INTERVAL 4096 @@ -222,9 +228,24 @@ do { \ #define STACK_CHECK_PROBE_LOAD 0 #endif -/* This value is arbitrary, but should be sufficient for most machines. */ +/* This is a kludge to try to capture the discrepancy between the old + mechanism (generic stack checking) and the new mechanism (static + builtin stack checking). STACK_CHECK_PROTECT needs to be bumped + for the latter because part of the protection area is effectively + included in STACK_CHECK_MAX_FRAME_SIZE for the former. */ +#ifdef STACK_CHECK_PROTECT +#define STACK_OLD_CHECK_PROTECT STACK_CHECK_PROTECT +#else +#define STACK_OLD_CHECK_PROTECT \ + (USING_SJLJ_EXCEPTIONS ? 75 * UNITS_PER_WORD : 8 * 1024) +#endif + +/* Minimum amount of stack required to recover from an anticipated stack + overflow detection. The default value conveys an estimate of the amount + of stack required to propagate an exception. */ #ifndef STACK_CHECK_PROTECT -#define STACK_CHECK_PROTECT (75 * UNITS_PER_WORD) +#define STACK_CHECK_PROTECT \ + (USING_SJLJ_EXCEPTIONS ? 75 * UNITS_PER_WORD : 12 * 1024) #endif /* Make the maximum frame size be the largest we can and still only need diff --git a/gcc/flags.h b/gcc/flags.h index cfd278f747e..1de81f8e13b 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -254,6 +254,27 @@ extern int flag_var_tracking; warning message in case flag was set by -fprofile-{generate,use}. */ extern bool flag_speculative_prefetching_set; +/* Type of stack check. */ +enum stack_check_type +{ + /* Do not check the stack. */ + NO_STACK_CHECK = 0, + + /* Check the stack generically, i.e. assume no specific support + from the target configuration files. */ + GENERIC_STACK_CHECK, + + /* Check the stack and rely on the target configuration files to + check the static frame of functions, i.e. use the generic + mechanism only for dynamic stack allocations. */ + STATIC_BUILTIN_STACK_CHECK, + + /* Check the stack and entirely rely on the target configuration + files, i.e. do not use the generic mechanism at all. */ + FULL_BUILTIN_STACK_CHECK +}; +extern enum stack_check_type flag_stack_check; + /* Returns TRUE if generated code should match ABI version N or greater is in use. */ diff --git a/gcc/function.c b/gcc/function.c index 98b8da07365..da26dc7d114 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -3236,7 +3236,7 @@ gimplify_parameters (void) walk_tree_without_duplicates (&data.passed_type, gimplify_parm_type, &stmts); - if (!TREE_CONSTANT (DECL_SIZE (parm))) + if (TREE_CODE (DECL_SIZE_UNIT (parm)) != INTEGER_CST) { gimplify_one_sizepos (&DECL_SIZE (parm), &stmts); gimplify_one_sizepos (&DECL_SIZE_UNIT (parm), &stmts); @@ -3250,9 +3250,12 @@ gimplify_parameters (void) { tree local, t; - /* For constant sized objects, this is trivial; for + /* For constant-sized objects, this is trivial; for variable-sized objects, we have to play games. */ - if (TREE_CONSTANT (DECL_SIZE (parm))) + if (TREE_CODE (DECL_SIZE_UNIT (parm)) == INTEGER_CST + && !(flag_stack_check == GENERIC_STACK_CHECK + && compare_tree_int (DECL_SIZE_UNIT (parm), + STACK_CHECK_MAX_VAR_SIZE) > 0)) { local = create_tmp_var (type, get_name (parm)); DECL_IGNORED_P (local) = 0; @@ -4480,10 +4483,10 @@ expand_function_end (void) if (arg_pointer_save_area && ! crtl->arg_pointer_save_area_init) get_arg_pointer_save_area (); - /* If we are doing stack checking and this function makes calls, + /* If we are doing generic stack checking and this function makes calls, do a stack probe at the start of the function to ensure we have enough space for another stack frame. */ - if (flag_stack_check && ! STACK_CHECK_BUILTIN) + if (flag_stack_check == GENERIC_STACK_CHECK) { rtx insn, seq; @@ -4491,7 +4494,7 @@ expand_function_end (void) if (CALL_P (insn)) { start_sequence (); - probe_stack_range (STACK_CHECK_PROTECT, + probe_stack_range (STACK_OLD_CHECK_PROTECT, GEN_INT (STACK_CHECK_MAX_FRAME_SIZE)); seq = get_insns (); end_sequence (); diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 43c8df991fc..b0b5e78968d 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1447,7 +1447,11 @@ gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p) { tree init = DECL_INITIAL (decl); - if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) + if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST + || (!TREE_STATIC (decl) + && flag_stack_check == GENERIC_STACK_CHECK + && compare_tree_int (DECL_SIZE_UNIT (decl), + STACK_CHECK_MAX_VAR_SIZE) > 0)) gimplify_vla_decl (decl, seq_p); if (init && init != error_mark_node) diff --git a/gcc/opts.c b/gcc/opts.c index 8dd8b8265fd..7d582297eb6 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "tree.h" #include "rtl.h" +#include "expr.h" #include "ggc.h" #include "output.h" #include "langhooks.h" @@ -1900,6 +1901,37 @@ common_handle_option (size_t scode, const char *arg, int value, flag_sched_stalled_insns_dep = value; break; + case OPT_fstack_check_: + if (!strcmp (arg, "no")) + flag_stack_check = NO_STACK_CHECK; + else if (!strcmp (arg, "generic")) + /* This is the old stack checking method. */ + flag_stack_check = STACK_CHECK_BUILTIN + ? FULL_BUILTIN_STACK_CHECK + : GENERIC_STACK_CHECK; + else if (!strcmp (arg, "specific")) + /* This is the new stack checking method. */ + flag_stack_check = STACK_CHECK_BUILTIN + ? FULL_BUILTIN_STACK_CHECK + : STACK_CHECK_STATIC_BUILTIN + ? STATIC_BUILTIN_STACK_CHECK + : GENERIC_STACK_CHECK; + else + warning (0, "unknown stack check parameter \"%s\"", arg); + break; + + case OPT_fstack_check: + /* This is the same as the "specific" mode above. */ + if (value) + flag_stack_check = STACK_CHECK_BUILTIN + ? FULL_BUILTIN_STACK_CHECK + : STACK_CHECK_STATIC_BUILTIN + ? STATIC_BUILTIN_STACK_CHECK + : GENERIC_STACK_CHECK; + else + flag_stack_check = NO_STACK_CHECK; + break; + case OPT_fstack_limit: /* The real switch is -fno-stack-limit. */ if (value) diff --git a/gcc/reload1.c b/gcc/reload1.c index 3abd6b24e33..3ee0fc37cfa 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1301,9 +1301,9 @@ reload (rtx first, int global) } } - /* If we are doing stack checking, give a warning if this function's - frame size is larger than we expect. */ - if (flag_stack_check && ! STACK_CHECK_BUILTIN) + /* If we are doing generic stack checking, give a warning if this + function's frame size is larger than we expect. */ + if (flag_stack_check == GENERIC_STACK_CHECK) { HOST_WIDE_INT size = get_frame_size () + STACK_CHECK_FIXED_FRAME_SIZE; static int verbose_warned = 0; diff --git a/gcc/stmt.c b/gcc/stmt.c index 38d7b439aec..f05cd0956fc 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -1867,8 +1867,8 @@ expand_decl (tree decl) SET_DECL_RTL (decl, gen_rtx_MEM (BLKmode, const0_rtx)); else if (DECL_SIZE (decl) == 0) - /* Variable with incomplete type. */ { + /* Variable with incomplete type. */ rtx x; if (DECL_INITIAL (decl) == 0) /* Error message was already done; now avoid a crash. */ @@ -1899,16 +1899,15 @@ expand_decl (tree decl) TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl)))); } - else if (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST - && ! (flag_stack_check && ! STACK_CHECK_BUILTIN - && 0 < compare_tree_int (DECL_SIZE_UNIT (decl), - STACK_CHECK_MAX_VAR_SIZE))) + else { - /* Variable of fixed size that goes on the stack. */ rtx oldaddr = 0; rtx addr; rtx x; + /* Variable-sized decls are dealt with in the gimplifier. */ + gcc_assert (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST); + /* If we previously made RTL for this decl, it must be an array whose size was determined by the initializer. The old address was a register; set that register now @@ -1936,41 +1935,6 @@ expand_decl (tree decl) emit_move_insn (oldaddr, addr); } } - else - /* Dynamic-size object: must push space on the stack. */ - { - rtx address, size, x; - - /* Record the stack pointer on entry to block, if have - not already done so. */ - do_pending_stack_adjust (); - - /* Compute the variable's size, in bytes. This will expand any - needed SAVE_EXPRs for the first time. */ - size = expand_normal (DECL_SIZE_UNIT (decl)); - free_temp_slots (); - - /* Allocate space on the stack for the variable. Note that - DECL_ALIGN says how the variable is to be aligned and we - cannot use it to conclude anything about the alignment of - the size. */ - address = allocate_dynamic_stack_space (size, NULL_RTX, - TYPE_ALIGN (TREE_TYPE (decl))); - - /* Reference the variable indirect through that rtx. */ - x = gen_rtx_MEM (DECL_MODE (decl), address); - set_mem_attributes (x, decl, 1); - SET_DECL_RTL (decl, x); - - - /* Indicate the alignment we actually gave this variable. */ -#ifdef STACK_BOUNDARY - DECL_ALIGN (decl) = STACK_BOUNDARY; -#else - DECL_ALIGN (decl) = BIGGEST_ALIGNMENT; -#endif - DECL_USER_ALIGN (decl) = 0; - } } /* Emit code to save the current value of stack. */ diff --git a/gcc/toplev.c b/gcc/toplev.c index bb49a970b49..269086911c8 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -306,6 +306,9 @@ rtx stack_limit_rtx; to optimize, debug_info_level and debug_hooks in process_options (). */ int flag_var_tracking = AUTODETECT_VALUE; +/* Type of stack check. */ +enum stack_check_type flag_stack_check = NO_STACK_CHECK; + /* True if the user has tagged the function with the 'section' attribute. */ |