OSDN Git Service

* tree-ssa-ccp.c (optimize_stack_restore): Relax the conditions under
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 27 Sep 2009 23:22:28 +0000 (23:22 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 27 Sep 2009 23:22:28 +0000 (23:22 +0000)
        which we remove __builtin_stack_restore.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr41469.c
gcc/testsuite/gcc.dg/tree-ssa/pr41469-1.c [new file with mode: 0644]
gcc/tree-ssa-ccp.c

index 7a2cce6..d1e8737 100644 (file)
@@ -1,3 +1,8 @@
+2009-09-27  Richard Henderson  <rth@redhat.com>
+
+       * tree-ssa-ccp.c (optimize_stack_restore): Relax the conditions under
+       which we remove __builtin_stack_restore.
+
 2009-09-27  Bernd Schmidt  <bernd.schmidt@analog.com>
 
        * loop-iv.c (iv_analyze_op): Use function_invariant_p, not CONSTANT_P,
index 36471f5..e7550e7 100644 (file)
@@ -1,3 +1,8 @@
+2009-09-27  Richard Henderson  <rth@redhat.com>
+
+       * gcc.c-torture/compile/pr41469.c: Add -fexceptions.
+       * testsuite/gcc.dg/tree-ssa/pr41469-1.c: New.
+
 2009-09-26  Andreas Schwab  <schwab@linux-m68k.org>
 
        PR c/41476
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr41469-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr41469-1.c
new file mode 100644 (file)
index 0000000..cee2c08
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fexceptions -fdump-tree-optimized" } */
+
+void af (void *a);
+
+void
+bf (void)
+{
+  int i = 1;
+  char v[i];
+  af (v);
+}
+
+/* { 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" } } */
index 4542403..85159b2 100644 (file)
@@ -3089,9 +3089,8 @@ fold_stmt_inplace (gimple stmt)
 static tree
 optimize_stack_restore (gimple_stmt_iterator i)
 {
-  tree callee, rhs;
-  gimple stmt, stack_save;
-  gimple_stmt_iterator stack_save_gsi;
+  tree callee;
+  gimple stmt;
 
   basic_block bb = gsi_bb (i);
   gimple call = gsi_stmt (i);
@@ -3115,32 +3114,49 @@ optimize_stack_restore (gimple_stmt_iterator i)
        return NULL_TREE;
 
       if (DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE)
-       break;
+       goto second_stack_restore;
     }
 
-  if (gsi_end_p (i)
-      && (! single_succ_p (bb)
-         || single_succ_edge (bb)->dest != EXIT_BLOCK_PTR))
+  if (!gsi_end_p (i))
     return NULL_TREE;
 
-  stack_save = SSA_NAME_DEF_STMT (gimple_call_arg (call, 0));
-  if (gimple_code (stack_save) != GIMPLE_CALL
-      || gimple_call_lhs (stack_save) != gimple_call_arg (call, 0)
-      || stmt_could_throw_p (stack_save)
-      || !has_single_use (gimple_call_arg (call, 0)))
-    return NULL_TREE;
+  /* Allow one successor of the exit block, or zero successors.  */
+  switch (EDGE_COUNT (bb->succs))
+    {
+    case 0:
+      break;
+    case 1:
+      if (single_succ_edge (bb)->dest != EXIT_BLOCK_PTR)
+       return NULL_TREE;
+      break;
+    default:
+      return NULL_TREE;
+    }
+ second_stack_restore:
 
-  callee = gimple_call_fndecl (stack_save);
-  if (!callee
-      || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
-      || DECL_FUNCTION_CODE (callee) != BUILT_IN_STACK_SAVE
-      || gimple_call_num_args (stack_save) != 0)
-    return NULL_TREE;
+  /* If there's exactly one use, then zap the call to __builtin_stack_save.
+     If there are multiple uses, then the last one should remove the call.
+     In any case, whether the call to __builtin_stack_save can be removed
+     or not is irrelevant to removing the call to __builtin_stack_restore.  */
+  if (has_single_use (gimple_call_arg (call, 0)))
+    {
+      gimple stack_save = SSA_NAME_DEF_STMT (gimple_call_arg (call, 0));
+      if (is_gimple_call (stack_save))
+       {
+         callee = gimple_call_fndecl (stack_save);
+         if (callee
+             && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
+             && DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE)
+           {
+             gimple_stmt_iterator stack_save_gsi;
+             tree rhs;
 
-  stack_save_gsi = gsi_for_stmt (stack_save);
-  rhs = build_int_cst (TREE_TYPE (gimple_call_arg (call, 0)), 0);
-  if (!update_call_from_tree (&stack_save_gsi, rhs))
-    return NULL_TREE;
+             stack_save_gsi = gsi_for_stmt (stack_save);
+             rhs = build_int_cst (TREE_TYPE (gimple_call_arg (call, 0)), 0);
+             update_call_from_tree (&stack_save_gsi, rhs);
+           }
+       }
+    }
 
   /* No effect, so the statement will be deleted.  */
   return integer_zero_node;