OSDN Git Service

PR middle-end/23848
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 15 Nov 2007 19:02:54 +0000 (19:02 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 15 Nov 2007 19:02:54 +0000 (19:02 +0000)
* tree-ssa-ccp.c (optimize_stack_restore): New function.
(execute_fold_all_builtins): Call optimize_stack_restore for
BUILT_IN_STACK_RESTORE.

* gcc.dg/tree-ssa/pr23848-1.c: New test.
* gcc.dg/tree-ssa/pr23848-2.c: New test.
* gcc.dg/tree-ssa/pr23848-3.c: New test.
* gcc.dg/tree-ssa/pr23848-4.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130206 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr23848-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr23848-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr23848-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr23848-4.c [new file with mode: 0644]
gcc/tree-ssa-ccp.c

index 95efbfa..ba07292 100644 (file)
@@ -1,3 +1,10 @@
+2007-11-15  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/23848
+       * tree-ssa-ccp.c (optimize_stack_restore): New function.
+       (execute_fold_all_builtins): Call optimize_stack_restore for
+       BUILT_IN_STACK_RESTORE.
+
 2007-11-15  Paolo Bonzini  <bonzini@gnu.org>
 
        * fwprop.c (try_fwprop_subst): Skip profitability check for forward
index b3e26c0..5d00b2d 100644 (file)
@@ -1,3 +1,11 @@
+2007-11-15  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/23848
+       * gcc.dg/tree-ssa/pr23848-1.c: New test.
+       * gcc.dg/tree-ssa/pr23848-2.c: New test.
+       * gcc.dg/tree-ssa/pr23848-3.c: New test.
+       * gcc.dg/tree-ssa/pr23848-4.c: New test.
+
 2007-11-15  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/33917
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23848-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23848-1.c
new file mode 100644 (file)
index 0000000..08916e4
--- /dev/null
@@ -0,0 +1,32 @@
+/* PR middle-end/23848 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+void bar1 (char *, int);
+void foo1 (int size)
+{
+  char temp[size];
+  temp[size-1] = '\0';
+  bar1 (temp, size);
+}
+
+void bar2 (char *, char *, char *, char *, int);
+void foo2 (int size)
+{
+  char temp[size];
+  temp[size-1] = '\0';
+  {
+    char temp2[size];
+    {
+      char temp3[size];
+      {
+       char temp4[size];
+       bar2 (temp, temp2, temp3, temp4, size);
+      }
+    }
+  }
+}
+
+/* { dg-final { scan-tree-dump-not "__builtin_stack_save" "optimized"} } */
+/* { dg-final { scan-tree-dump-not "__builtin_stack_restore" "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23848-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23848-2.c
new file mode 100644 (file)
index 0000000..c969146
--- /dev/null
@@ -0,0 +1,25 @@
+/* PR middle-end/23848 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+void bar (char *, char *, char *, char *, int);
+void foo (int size)
+{
+  char temp[size];
+  temp[size-1] = '\0';
+  {
+    char temp2[size];
+    {
+      char temp3[size];
+      {
+       char temp4[size];
+       bar (temp, temp2, temp3, temp4, size);
+      }
+    }
+    bar (temp, temp2, (char *) 0, (char *) 0, size);
+  }
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_stack_save" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "__builtin_stack_restore" 1 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23848-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23848-3.c
new file mode 100644 (file)
index 0000000..d255504
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR middle-end/23848 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+void bar (int, char *, char *, char *, char *, int);
+void foo (int size)
+{
+  int i;
+  for (i = 0; i < size; i++)
+    {
+      char temp[size];
+      temp[size-1] = '\0';
+      {
+       char temp2[size];
+       {
+         char temp3[size];
+         {
+           char temp4[size];
+           bar (i, temp, temp2, temp3, temp4, size);
+         }
+       }
+      }
+    }
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_stack_save" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "__builtin_stack_restore" 1 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23848-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23848-4.c
new file mode 100644 (file)
index 0000000..66b21b8
--- /dev/null
@@ -0,0 +1,25 @@
+/* PR middle-end/23848 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+void bar (char *, char *, char *, char *, int);
+void foo (int size)
+{
+  char temp[size];
+  temp[size-1] = '\0';
+  {
+    char temp2[size];
+    {
+      char temp3[size];
+      {
+       char temp4[size];
+       bar (temp, temp2, temp3, temp4, size);
+      }
+    }
+    __asm __volatile ("" : : "r" (&temp[0]), "r" (&temp2[0]) : "memory");
+  }
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_stack_save" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "__builtin_stack_restore" 1 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
index 301316d..0fc4b47 100644 (file)
@@ -2601,6 +2601,76 @@ fold_stmt_inplace (tree stmt)
   return changed;
 }
 \f
+/* Try to optimize out __builtin_stack_restore.  Optimize it out
+   if there is another __builtin_stack_restore in the same basic
+   block and no calls or ASM_EXPRs are in between, or if this block's
+   only outgoing edge is to EXIT_BLOCK and there are no calls or
+   ASM_EXPRs after this __builtin_stack_restore.  */
+
+static tree
+optimize_stack_restore (basic_block bb, tree call, block_stmt_iterator i)
+{
+  tree stack_save, stmt, callee;
+
+  if (TREE_CODE (call) != CALL_EXPR
+      || call_expr_nargs (call) != 1
+      || TREE_CODE (CALL_EXPR_ARG (call, 0)) != SSA_NAME
+      || !POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (call, 0))))
+    return NULL_TREE;
+
+  for (bsi_next (&i); !bsi_end_p (i); bsi_next (&i))
+    {
+      tree call;
+
+      stmt = bsi_stmt (i);
+      if (TREE_CODE (stmt) == ASM_EXPR)
+       return NULL_TREE;
+      call = get_call_expr_in (stmt);
+      if (call == NULL)
+       continue;
+
+      callee = get_callee_fndecl (call);
+      if (!callee || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
+       return NULL_TREE;
+
+      if (DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE)
+       break;
+    }
+
+  if (bsi_end_p (i)
+      && (! single_succ_p (bb)
+         || single_succ_edge (bb)->dest != EXIT_BLOCK_PTR))
+    return NULL_TREE;
+
+  stack_save = SSA_NAME_DEF_STMT (CALL_EXPR_ARG (call, 0));
+  if (TREE_CODE (stack_save) != GIMPLE_MODIFY_STMT
+      || GIMPLE_STMT_OPERAND (stack_save, 0) != CALL_EXPR_ARG (call, 0)
+      || TREE_CODE (GIMPLE_STMT_OPERAND (stack_save, 1)) != CALL_EXPR
+      || tree_could_throw_p (stack_save)
+      || !has_single_use (CALL_EXPR_ARG (call, 0)))
+    return NULL_TREE;
+
+  callee = get_callee_fndecl (GIMPLE_STMT_OPERAND (stack_save, 1));
+  if (!callee
+      || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
+      || DECL_FUNCTION_CODE (callee) != BUILT_IN_STACK_SAVE
+      || call_expr_nargs (GIMPLE_STMT_OPERAND (stack_save, 1)) != 0)
+    return NULL_TREE;
+
+  stmt = stack_save;
+  push_stmt_changes (&stmt);
+  if (!set_rhs (&stmt,
+               build_int_cst (TREE_TYPE (CALL_EXPR_ARG (call, 0)), 0)))
+    {
+      discard_stmt_changes (&stmt);
+      return NULL_TREE;
+    }
+  gcc_assert (stmt == stack_save);
+  pop_stmt_changes (&stmt);
+
+  return integer_zero_node;
+}
+\f
 /* Convert EXPR into a GIMPLE value suitable for substitution on the
    RHS of an assignment.  Insert the necessary statements before
    iterator *SI_P. 
@@ -2685,6 +2755,12 @@ execute_fold_all_builtins (void)
                result = integer_zero_node;
                break;
 
+             case BUILT_IN_STACK_RESTORE:
+               result = optimize_stack_restore (bb, *stmtp, i);
+               if (result)
+                 break;
+               /* FALLTHRU */
+
              default:
                bsi_next (&i);
                continue;