]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cfgexpand.c (defer_stack_allocation): When optimization is enabled...
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 14 Nov 2013 23:58:39 +0000 (23:58 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 14 Nov 2013 23:58:39 +0000 (23:58 +0000)
* cfgexpand.c (defer_stack_allocation): When optimization is enabled,
defer allocation of DECL_IGNORED_P variables at toplevel unless really
small.  Factorize size threshold computation from the existing one.
(expand_used_vars): Refine comment.

From-SVN: r204830

gcc/ChangeLog
gcc/cfgexpand.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/stack_usage1b.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/stack_usage1c.adb [new file with mode: 0644]

index 5286637a72127eba905afbe067eb9c7e049f7b1a..bdee3162a64adc46a54bc7f1f5f3dc7f0455a369 100644 (file)
@@ -1,3 +1,10 @@
+2013-11-14   Olivier Hainque  <hainque@adacore.com>
+
+       * cfgexpand.c (defer_stack_allocation): When optimization is enabled,
+       defer allocation of DECL_IGNORED_P variables at toplevel unless really
+       small.  Factorize size threshold computation from the existing one.
+       (expand_used_vars): Refine comment.
+
 2013-11-14  Cong Hou  <congh@google.com>
 
        * tree-vectorizer.h (struct dr_with_seg_len): Remove the base
index 9b480a247bbf671522162498781b5cb48192ada2..3100688d72e2093297944ba3ed8b7a42578b01b9 100644 (file)
@@ -1130,6 +1130,12 @@ 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_low_cst (DECL_SIZE_UNIT (var), 1)
+       < 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.  */
@@ -1141,8 +1147,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)
@@ -1154,9 +1167,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_low_cst (DECL_SIZE_UNIT (var), 1)
-          < PARAM_VALUE (PARAM_MIN_SIZE_FOR_STACK_SHARING)))
+  if (optimize == 0 && smallish)
     return false;
 
   return true;
@@ -1676,9 +1687,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;
 
index 91baab29c910890a7cedf9c18470357c3c44a52b..2dc4a31ef2f192c42f6979d85e9cf86d6f5e8708 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-14  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/stack_usage1b.adb: New test.
+       * gnat.dg/stack_usage1c.adb: Likewise.
+
 2013-11-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gnat.dg/specs/addr1.ads: Revert the last change.
diff --git a/gcc/testsuite/gnat.dg/stack_usage1b.adb b/gcc/testsuite/gnat.dg/stack_usage1b.adb
new file mode 100644 (file)
index 0000000..4129c0d
--- /dev/null
@@ -0,0 +1,39 @@
+-- { dg-do compile }
+-- { dg-options "-O -fstack-usage" }
+
+with Stack_Usage1_Pkg; use Stack_Usage1_Pkg;
+
+procedure Stack_Usage1b is
+
+   A : Integer := Ident_Int (123);
+
+begin
+   case A is
+       when 0 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 1 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 2 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 3 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 4 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 5 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 6 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 7 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 8 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 9 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when others =>
+          null;
+   end case;
+
+end Stack_Usage1b;
+
+-- { dg-final { scan-stack-usage "\t\[0-9\]\[0-9\]\t" { target i?86-*-* x86_64-*-* } } }
+-- { dg-final { cleanup-stack-usage } }
diff --git a/gcc/testsuite/gnat.dg/stack_usage1c.adb b/gcc/testsuite/gnat.dg/stack_usage1c.adb
new file mode 100644 (file)
index 0000000..41b7a60
--- /dev/null
@@ -0,0 +1,39 @@
+-- { dg-do compile }
+-- { dg-options "-O2 -fstack-usage" }
+
+with Stack_Usage1_Pkg; use Stack_Usage1_Pkg;
+
+procedure Stack_Usage1c is
+
+   A : Integer := Ident_Int (123);
+
+begin
+   case A is
+       when 0 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 1 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 2 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 3 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 4 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 5 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 6 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 7 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 8 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when 9 =>
+          My_Proc (R'(Ident_Int(0), Ident_Int(1), Ident_Int(2), Ident_Int(3), Ident_Int(4), Ident_Int(5), Ident_Int(6), Ident_Int(7), Ident_Int(8), Ident_Int(9)));
+       when others =>
+          null;
+   end case;
+
+end Stack_Usage1c;
+
+-- { dg-final { scan-stack-usage "\t\[0-9\]\[0-9\]\t" { target i?86-*-* x86_64-*-* } } }
+-- { dg-final { cleanup-stack-usage } }