===================================================================
@@ -924,7 +924,7 @@ See S/390 and zSeries Options.
-fshort-double -fshort-wchar @gol
-fverbose-asm -fpack-struct[=@var{n}] -fstack-check @gol
-fstack-limit-register=@var{reg} -fstack-limit-symbol=@var{sym} @gol
--fno-stack-limit @gol
+-fno-stack-limit -fsplit-stack @gol
-fleading-underscore -ftls-model=@var{model} @gol
-ftrapv -fwrapv -fbounds-check @gol
-fvisibility}
@@ -17916,6 +17916,25 @@ and grows downwards, you can use the fla
@option{-Wl,--defsym,__stack_limit=0x7ffe0000} to enforce a stack limit
of 128KB@. Note that this may only work with the GNU linker.
+@item -fsplit-stack
+@opindex fsplit-stack
+Generate code to automatically split the stack before it overflows.
+The resulting program has a discontiguous stack which can only
+overflow if the program is unable to allocate any more memory. This
+is most useful when running threaded programs, as it is no longer
+necessary to calculate a good stack size to use for each thread. This
+is currently only implemented for the i386 and x86_64 backends running
+GNU/Linux.
+
+When code compiled with @option{-fsplit-stack} calls code compiled
+without @option{-fsplit-stack}, there may not be much stack space
+available for the latter code to run. If compiling all code,
+including library code, with @option{-fsplit-stack} is not an option,
+then the linker can fix up these calls so that the code compiled
+without @option{-fsplit-stack} always has a large stack. Support for
+this is implemented in the gold linker in GNU binutils release 2.21
+and later.
+
@item -fleading-underscore
@opindex fleading-underscore
This option and its counterpart, @option{-fno-leading-underscore}, forcibly
===================================================================
@@ -1926,7 +1926,8 @@ attributes are currently defined for fun
@code{returns_twice}, @code{noinline}, @code{noclone},
@code{always_inline}, @code{flatten}, @code{pure}, @code{const},
@code{nothrow}, @code{sentinel}, @code{format}, @code{format_arg},
-@code{no_instrument_function}, @code{section}, @code{constructor},
+@code{no_instrument_function}, @code{no_split_stack},
+@code{section}, @code{constructor},
@code{destructor}, @code{used}, @code{unused}, @code{deprecated},
@code{weak}, @code{malloc}, @code{alias}, @code{ifunc},
@code{warn_unused_result}, @code{nonnull}, @code{gnu_inline},
@@ -2831,6 +2832,14 @@ If @option{-finstrument-functions} is gi
be generated at entry and exit of most user-compiled functions.
Functions with this attribute will not be so instrumented.
+@item no_split_stack
+@cindex @code{no_split_stack} function attribute
+@opindex fsplit-stack
+If @option{-fsplit-stack} is given, functions will have a small
+prologue which decides whether to split the stack. Functions with the
+@code{no_split_stack} attribute will not have that prologue, and thus
+may run with only a small amount of stack space available.
+
@item noinline
@cindex @code{noinline} function attribute
This function attribute prevents a function from being considered for
===================================================================
@@ -4960,6 +4960,10 @@ The default version of this hook invokes
normally defined in @file{libgcc2.c}.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_SUPPORTS_SPLIT_STACK (bool)
+Whether this target supports splitting the stack. This is called after options have been parsed, so the target may reject splitting the stack in some configurations. The default version of this hook returns false. If REPORT is true, this function may issue a warning or error; if REPORT is false, it must simply return a value
+@end deftypefn
+
@node Varargs
@section Implementing the Varargs Macros
@cindex varargs implementation
===================================================================
@@ -4960,6 +4960,8 @@ The default version of this hook invokes
normally defined in @file{libgcc2.c}.
@end deftypefn
+@hook TARGET_SUPPORTS_SPLIT_STACK
+
@node Varargs
@section Implementing the Varargs Macros
@cindex varargs implementation
===================================================================
@@ -1679,6 +1679,16 @@ DEFHOOK
tree, (void),
default_external_stack_protect_fail)
+DEFHOOK
+(supports_split_stack,
+ "Whether this target supports splitting the stack. This is called\
+ after options have been parsed, so the target may reject splitting\
+ the stack in some configurations. The default version of this hook\
+ returns false. If REPORT is true, this function may issue a warning\
+ or error; if REPORT is false, it must simply return a value",
+ bool, (bool),
+ hook_bool_bool_false)
+
/* Returns NULL if target supports the insn within a doloop block,
otherwise it returns an error message. */
DEFHOOK
===================================================================
@@ -357,6 +357,7 @@ static tree handle_type_generic_attribut
static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
static tree handle_target_attribute (tree *, tree, tree, int, bool *);
static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
+static tree handle_no_split_stack_attribute (tree *, tree, tree, int, bool *);
static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *);
static void check_function_nonnull (tree, int, tree *);
@@ -658,6 +659,8 @@ const struct attribute_spec c_common_att
handle_target_attribute },
{ "optimize", 1, -1, true, false, false,
handle_optimize_attribute },
+ { "no_split_stack", 0, 0, true, false, false,
+ handle_no_split_stack_attribute },
/* For internal use (marking of builtins and runtime functions) only.
The name contains space to prevent its usage in source code. */
{ "fn spec", 1, 1, false, true, true,
@@ -7816,6 +7819,32 @@ handle_optimize_attribute (tree *node, t
return NULL_TREE;
}
+
+/* Handle a "no_split_stack" attribute. */
+
+static tree
+handle_no_split_stack_attribute (tree *node, tree name,
+ tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags),
+ bool *no_add_attrs)
+{
+ tree decl = *node;
+
+ if (TREE_CODE (decl) != FUNCTION_DECL)
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "%qE attribute applies only to functions", name);
+ *no_add_attrs = true;
+ }
+ else if (DECL_INITIAL (decl))
+ {
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "can%'t set %qE attribute after definition", name);
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
/* Check for valid arguments being passed to a function.
ATTRS is a list of attributes. There are NARGS arguments in the array
===================================================================
@@ -584,6 +584,16 @@ proper position among the other output f
#define MFLIB_SPEC "%{fmudflap|fmudflapth: -export-dynamic}"
#endif
+/* When using -fsplit-stack we need to wrap pthread_create, in order
+ to initialize the stack guard. We always use wrapping, rather than
+ shared library ordering, and we keep the wrapper function in
+ libgcc. This is not yet a real spec, though it could become one;
+ it is currently just stuffed into LINK_SPEC. FIXME: This wrapping
+ only works with GNU ld and gold. FIXME: This is incompatible with
+ -fmudflap when linking statically, which wants to do its own
+ wrapping. */
+#define STACK_SPLIT_SPEC " %{fsplit-stack: --wrap=pthread_create}"
+
/* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
included. */
#ifndef LIBGCC_SPEC
@@ -696,7 +706,8 @@ proper position among the other output f
"%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
%{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
%{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
- %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)} %(mflib)\
+ %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
+ %(mflib) " STACK_SPLIT_SPEC "\
%{fprofile-arcs|fprofile-generate*|coverage:-lgcov}\
%{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
===================================================================
@@ -1086,6 +1086,20 @@ decode_options (unsigned int argc, const
check option consistency. */
if (flag_lto && flag_whopr)
error ("-flto and -fwhopr are mutually exclusive");
+
+ /* We initialize flag_split_stack to -1 so that targets can set a
+ default value if they choose based on other options. */
+ if (flag_split_stack == -1)
+ flag_split_stack = 0;
+ else
+ {
+ if (!targetm.supports_split_stack (true))
+ {
+ error ("%<-fsplit-stack%> is not supported by "
+ "this compiler configuration");
+ flag_split_stack = 0;
+ }
+ }
}
#define LEFT_COLUMN 27
===================================================================
@@ -1249,6 +1249,10 @@ fsplit-ivs-in-unroller
Common Report Var(flag_split_ivs_in_unroller) Init(1) Optimization
Split lifetimes of induction variables when loops are unrolled
+fsplit-stack
+Common Report Var(flag_split_stack) Init(-1)
+Generate discontiguous stack frames
+
fsplit-wide-types
Common Report Var(flag_split_wide_types) Optimization
Split wide types into independent registers