summaryrefslogtreecommitdiff
path: root/gcc/cfgcleanup.c
diff options
context:
space:
mode:
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-05 12:59:23 +0000
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-05 12:59:23 +0000
commit1f021f971fee1972354d61608fae5ab0f9175538 (patch)
tree092a063b47d0bf2e253befae6fbbc597612758ed /gcc/cfgcleanup.c
parent3eebeec678ca0cfd97cb2b84e2a30378c9b548f7 (diff)
downloadgcc-1f021f971fee1972354d61608fae5ab0f9175538.tar.gz
* doc/invoke.texi (-fshrink-wrap): Document.
* opts.c (default_options_table): Add it. * common.opt (fshrink-wrap): Add. * function.c (emit_return_into_block): Remove useless declaration. (record_hard_reg_uses_1, record_hard_reg_uses, frame_required_for_rtx, requires_stack_frame_p, gen_return_pattern): New static functions. (emit_return_into_block): New arg simple_p. All callers changed. Use gen_return_pattern. (thread_prologue_and_epilogue_insns): Implement shrink-wrapping. * config/i386/i386.md (return): Expand into a simple_return. (simple_return): New expander): (simple_return_internal, simple_return_internal_long, simple_return_pop_internal_long, simple_return_indirect_internal): Renamed from return_internal, return_internal_long, return_pop_internal_long and return_indirect_internal; changed to use simple_return. * config/i386/i386.c (ix86_expand_epilogue): Adjust to expand simple returns. (ix86_pad_returns): Likewise. * function.h (struct rtl_data): Add member shrink_wrapped. * cfgcleanup.c (outgoing_edges_match): If shrink-wrapped, edges that are not jumps or sibcalls can't be compared. * gcc.target/i386/sw-1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179553 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgcleanup.c')
-rw-r--r--gcc/cfgcleanup.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 20a409c4fae..b59cf7bc9f0 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -1488,6 +1488,16 @@ outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
edge e1, e2;
edge_iterator ei;
+ /* If we performed shrink-wrapping, edges to the EXIT_BLOCK_PTR can
+ only be distinguished for JUMP_INSNs. The two paths may differ in
+ whether they went through the prologue. Sibcalls are fine, we know
+ that we either didn't need or inserted an epilogue before them. */
+ if (crtl->shrink_wrapped
+ && single_succ_p (bb1) && single_succ (bb1) == EXIT_BLOCK_PTR
+ && !JUMP_P (BB_END (bb1))
+ && !(CALL_P (BB_END (bb1)) && SIBLING_CALL_P (BB_END (bb1))))
+ return false;
+
/* If BB1 has only one successor, we may be looking at either an
unconditional jump, or a fake edge to exit. */
if (single_succ_p (bb1)