diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-11-15 20:02:54 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-11-15 20:02:54 +0100 |
commit | cb8e078d3f0aa2a99eb9d14ba0f38354ffc181a6 (patch) | |
tree | 632c05815bb907003de31352c54fe7216c1a16a8 | |
parent | 62e66076c6c114aa150ff63478b41e8c834a6fcb (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr23848-1.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr23848-2.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr23848-3.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr23848-4.c | 25 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 76 |
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; |