diff options
author | Richard Henderson <rth@redhat.com> | 2009-09-27 16:22:28 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2009-09-27 16:22:28 -0700 |
commit | ff9d1adc12a4f8072592fa14845ce703233e365f (patch) | |
tree | 50f0b2694494a02c9c1094301ab9d7159c26b03d /gcc/tree-ssa-ccp.c | |
parent | cdf1bf8bb3311493aa9822bc9c8f6d94571fe82e (diff) | |
download | gcc-ff9d1adc12a4f8072592fa14845ce703233e365f.zip gcc-ff9d1adc12a4f8072592fa14845ce703233e365f.tar.gz gcc-ff9d1adc12a4f8072592fa14845ce703233e365f.tar.bz2 |
tree-ssa-ccp.c (optimize_stack_restore): Relax the conditions under which we remove __builtin_stack_restore.
* tree-ssa-ccp.c (optimize_stack_restore): Relax the conditions under
which we remove __builtin_stack_restore.
From-SVN: r152227
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r-- | gcc/tree-ssa-ccp.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 4542403..85159b2 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -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; |