summaryrefslogtreecommitdiff
path: root/gcc/cfgexpand.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r--gcc/cfgexpand.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index ff085bb3761..0bd4ef79bae 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -31,6 +31,8 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "bitmap.h"
#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
#include "gimple-ssa.h"
#include "cgraph.h"
#include "tree-cfg.h"
@@ -61,6 +63,14 @@ along with GCC; see the file COPYING3. If not see
#include "recog.h"
#include "output.h"
+/* Some systems use __main in a way incompatible with its use in gcc, in these
+ cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
+ give the same symbol without quotes for an alternative entry point. You
+ must define both, or neither. */
+#ifndef NAME__MAIN
+#define NAME__MAIN "__main"
+#endif
+
/* This variable holds information helping the rewriting of SSA trees
into RTL. */
struct ssaexpand SA;
@@ -1120,6 +1130,13 @@ expand_one_error_var (tree var)
static bool
defer_stack_allocation (tree var, bool toplevel)
{
+ /* Whether the variable is small enough for immediate allocation not to be
+ a problem with regard to the frame size. */
+ bool smallish
+ = (tree_to_uhwi (DECL_SIZE_UNIT (var))
+ < ((unsigned HOST_WIDE_INT)
+ PARAM_VALUE (PARAM_MIN_SIZE_FOR_STACK_SHARING)));
+
/* If stack protection is enabled, *all* stack variables must be deferred,
so that we can re-order the strings to the top of the frame.
Similarly for Address Sanitizer. */
@@ -1131,8 +1148,15 @@ defer_stack_allocation (tree var, bool toplevel)
if (DECL_ALIGN (var) > MAX_SUPPORTED_STACK_ALIGNMENT)
return true;
- /* Variables in the outermost scope automatically conflict with
- every other variable. The only reason to want to defer them
+ /* When optimization is enabled, DECL_IGNORED_P variables originally scoped
+ might be detached from their block and appear at toplevel when we reach
+ here. We want to coalesce them with variables from other blocks when
+ the immediate contribution to the frame size would be noticeable. */
+ if (toplevel && optimize > 0 && DECL_IGNORED_P (var) && !smallish)
+ return true;
+
+ /* Variables declared in the outermost scope automatically conflict
+ with every other variable. The only reason to want to defer them
at all is that, after sorting, we can more efficiently pack
small variables in the stack frame. Continue to defer at -O2. */
if (toplevel && optimize < 2)
@@ -1144,10 +1168,7 @@ defer_stack_allocation (tree var, bool toplevel)
other hand, we don't want the function's stack frame size to
get completely out of hand. So we avoid adding scalars and
"small" aggregates to the list at all. */
- if (optimize == 0
- && (tree_to_uhwi (DECL_SIZE_UNIT (var))
- < ((unsigned HOST_WIDE_INT)
- PARAM_VALUE (PARAM_MIN_SIZE_FOR_STACK_SHARING))))
+ if (optimize == 0 && smallish)
return false;
return true;
@@ -1603,9 +1624,15 @@ expand_used_vars (void)
replace_ssa_name_symbol (var, (tree) *slot);
}
+ /* Always allocate space for partitions based on VAR_DECLs. But for
+ those based on PARM_DECLs or RESULT_DECLs and which matter for the
+ debug info, there is no need to do so if optimization is disabled
+ because all the SSA_NAMEs based on these DECLs have been coalesced
+ into a single partition, which is thus assigned the canonical RTL
+ location of the DECLs. */
if (TREE_CODE (SSA_NAME_VAR (var)) == VAR_DECL)
expand_one_var (var, true, true);
- else
+ else if (DECL_IGNORED_P (SSA_NAME_VAR (var)) || optimize)
{
/* This is a PARM_DECL or RESULT_DECL. For those partitions that
contain the default def (representing the parm or result itself)
@@ -1661,9 +1688,11 @@ expand_used_vars (void)
else if (TREE_STATIC (var) || DECL_EXTERNAL (var))
expand_now = true;
- /* If the variable is not associated with any block, then it
- was created by the optimizers, and could be live anywhere
- in the function. */
+ /* Expand variables not associated with any block now. Those created by
+ the optimizers could be live anywhere in the function. Those that
+ could possibly have been scoped originally and detached from their
+ block will have their allocation deferred so we coalesce them with
+ others when optimization is enabled. */
else if (TREE_USED (var))
expand_now = true;