aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-11-15 20:02:54 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2007-11-15 20:02:54 +0100
commitcb8e078d3f0aa2a99eb9d14ba0f38354ffc181a6 (patch)
tree632c05815bb907003de31352c54fe7216c1a16a8
parent62e66076c6c114aa150ff63478b41e8c834a6fcb (diff)
downloadgcc-cb8e078d3f0aa2a99eb9d14ba0f38354ffc181a6.zip
gcc-cb8e078d3f0aa2a99eb9d14ba0f38354ffc181a6.tar.gz
gcc-cb8e078d3f0aa2a99eb9d14ba0f38354ffc181a6.tar.bz2
re PR middle-end/23848 (stack deallocation can be more efficient)
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. * 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. From-SVN: r130206
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr23848-1.c32
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr23848-2.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr23848-3.c28
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr23848-4.c25
-rw-r--r--gcc/tree-ssa-ccp.c76
7 files changed, 201 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 95efbfad..ba07292 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b3e26c0..5d00b2d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..08916e4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23848-1.c
@@ -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
index 0000000..c969146
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23848-2.c
@@ -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
index 0000000..d255504
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23848-3.c
@@ -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
index 0000000..66b21b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23848-4.c
@@ -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" } } */
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 301316d..0fc4b47 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2601,6 +2601,76 @@ fold_stmt_inplace (tree stmt)
return changed;
}
+/* 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;
+}
+
/* 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;