Implement -freuse-stack= option
From-SVN: r189413
This commit is contained in:
parent
2f01137541
commit
87e2a8fd39
@ -1,3 +1,12 @@
|
||||
2012-07-10 Xinliang David Li <davidxl@google.com>
|
||||
|
||||
* doc/invoke.texi: New option documented.
|
||||
* flag-types.h: New enum type.
|
||||
* gimplify.c (gimplify_bind_expr): Control
|
||||
clobber generation with new option.
|
||||
(gimplify_target_expr): Ditto.
|
||||
common.opt: New option.
|
||||
|
||||
2012-07-10 Julian Brown <julian@codesourcery.com>
|
||||
|
||||
* config/arm/arm.md (movsi): Don't split symbol refs here.
|
||||
|
@ -1247,6 +1247,22 @@ fif-conversion2
|
||||
Common Report Var(flag_if_conversion2) Optimization
|
||||
Perform conversion of conditional jumps to conditional execution
|
||||
|
||||
fstack-reuse=
|
||||
Common Joined RejectNegative Enum(stack_reuse_level) Var(flag_stack_reuse) Init(SR_ALL)
|
||||
-fstack-reuse=[all|named_vars|none] Set stack reuse level for local variables.
|
||||
|
||||
Enum
|
||||
Name(stack_reuse_level) Type(enum stack_reuse_level) UnknownError(unknown Stack Reuse Level %qs)
|
||||
|
||||
EnumValue
|
||||
Enum(stack_reuse_level) String(all) Value(SR_ALL)
|
||||
|
||||
EnumValue
|
||||
Enum(stack_reuse_level) String(named_vars) Value(SR_NAMED_VARS)
|
||||
|
||||
EnumValue
|
||||
Enum(stack_reuse_level) String(none) Value(SR_NONE)
|
||||
|
||||
ftree-loop-if-convert
|
||||
Common Report Var(flag_tree_loop_if_convert) Init(-1) Optimization
|
||||
Convert conditional jumps in innermost loops to branchless equivalents
|
||||
|
@ -990,6 +990,7 @@ See S/390 and zSeries Options.
|
||||
-fstack-limit-register=@var{reg} -fstack-limit-symbol=@var{sym} @gol
|
||||
-fno-stack-limit -fsplit-stack @gol
|
||||
-fleading-underscore -ftls-model=@var{model} @gol
|
||||
-fstack-reuse=@var{reuse_level} @gol
|
||||
-ftrapv -fwrapv -fbounds-check @gol
|
||||
-fvisibility -fstrict-volatile-bitfields -fsync-libcalls}
|
||||
@end table
|
||||
@ -19307,6 +19308,84 @@ indices used to access arrays are within the declared range. This is
|
||||
currently only supported by the Java and Fortran front ends, where
|
||||
this option defaults to true and false respectively.
|
||||
|
||||
@item -fstack-reuse=@var{reuse-level}
|
||||
@opindex fstack_reuse
|
||||
This option controls stack space reuse for user declared local/auto variables
|
||||
and compiler generated temporaries. @var{reuse_level} can be @samp{all},
|
||||
@samp{named_vars}, or @samp{none}. @samp{all} enables stack reuse for all
|
||||
local variables and temporaries, @samp{named_vars} enables the reuse only for
|
||||
user defined local variables with names, and @samp{none} disables stack reuse
|
||||
completely. The default value is @samp{all}. The option is needed when the
|
||||
program extends the lifetime of a scoped local variable or a compiler generated
|
||||
temporary beyond the end point defined by the language. When a lifetime of
|
||||
a variable ends, and if the variable lives in memory, the optimizing compiler
|
||||
has the freedom to reuse its stack space with other temporaries or scoped
|
||||
local variables whose live range does not overlap with it. Legacy code extending
|
||||
local lifetime will likely to break with the stack reuse optimization.
|
||||
|
||||
For example,
|
||||
|
||||
@smallexample
|
||||
int *p;
|
||||
@{
|
||||
int local1;
|
||||
|
||||
p = &local1;
|
||||
local1 = 10;
|
||||
....
|
||||
@}
|
||||
@{
|
||||
int local2;
|
||||
local2 = 20;
|
||||
...
|
||||
@}
|
||||
|
||||
if (*p == 10) // out of scope use of local1
|
||||
@{
|
||||
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
Another example:
|
||||
@smallexample
|
||||
|
||||
struct A
|
||||
@{
|
||||
A(int k) : i(k), j(k) @{ @}
|
||||
int i;
|
||||
int j;
|
||||
@};
|
||||
|
||||
A *ap;
|
||||
|
||||
void foo(const A& ar)
|
||||
@{
|
||||
ap = &ar;
|
||||
@}
|
||||
|
||||
void bar()
|
||||
@{
|
||||
foo(A(10)); // temp object's lifetime ends when foo returns
|
||||
|
||||
@{
|
||||
A a(20);
|
||||
....
|
||||
@}
|
||||
ap->i+= 10; // ap references out of scope temp whose space
|
||||
// is reused with a. What is the value of ap->i?
|
||||
@}
|
||||
|
||||
@end smallexample
|
||||
|
||||
The lifetime of a compiler generated temporary is well defined by the C++
|
||||
standard. When a lifetime of a temporary ends, and if the temporary lives
|
||||
in memory, the optimizing compiler has the freedom to reuse its stack
|
||||
space with other temporaries or scoped local variables whose live range
|
||||
does not overlap with it. However some of the legacy code relies on
|
||||
the behavior of older compilers in which temporaries' stack space is
|
||||
not reused, the aggressive stack reuse can lead to runtime errors. This
|
||||
option is used to control the temporary stack reuse optimization.
|
||||
|
||||
@item -ftrapv
|
||||
@opindex ftrapv
|
||||
This option generates traps for signed overflow on addition, subtraction,
|
||||
|
@ -106,6 +106,14 @@ enum symbol_visibility
|
||||
};
|
||||
#endif
|
||||
|
||||
/* The stack reuse level. */
|
||||
enum stack_reuse_level
|
||||
{
|
||||
SR_NONE,
|
||||
SR_NAMED_VARS,
|
||||
SR_ALL
|
||||
};
|
||||
|
||||
/* The algorithm used for the integrated register allocator (IRA). */
|
||||
enum ira_algorithm
|
||||
{
|
||||
|
@ -1247,7 +1247,8 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
|
||||
&& !DECL_HAS_VALUE_EXPR_P (t)
|
||||
/* Only care for variables that have to be in memory. Others
|
||||
will be rewritten into SSA names, hence moved to the top-level. */
|
||||
&& !is_gimple_reg (t))
|
||||
&& !is_gimple_reg (t)
|
||||
&& flag_stack_reuse != SR_NONE)
|
||||
{
|
||||
tree clobber = build_constructor (TREE_TYPE (t), NULL);
|
||||
TREE_THIS_VOLATILE (clobber) = 1;
|
||||
@ -5634,7 +5635,8 @@ gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
|
||||
/* Add a clobber for the temporary going out of scope, like
|
||||
gimplify_bind_expr. */
|
||||
if (gimplify_ctxp->in_cleanup_point_expr
|
||||
&& needs_to_live_in_memory (temp))
|
||||
&& needs_to_live_in_memory (temp)
|
||||
&& flag_stack_reuse == SR_ALL)
|
||||
{
|
||||
tree clobber = build_constructor (TREE_TYPE (temp), NULL);
|
||||
TREE_THIS_VOLATILE (clobber) = true;
|
||||
|
Loading…
Reference in New Issue
Block a user