diff options
author | Eric Botcazou <ebotcazou@libertysurf.fr> | 2004-07-17 20:12:37 +0200 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2004-07-17 18:12:37 +0000 |
commit | 6e456a105496a5058ccfdef441678f15de78b893 (patch) | |
tree | 644d0f4f5e087fec3c389cf35c1c4cc29f74be50 /gcc/resource.c | |
parent | 8a807136e16752e8024f34967cf2071e4c1c284f (diff) | |
download | gcc-6e456a105496a5058ccfdef441678f15de78b893.zip gcc-6e456a105496a5058ccfdef441678f15de78b893.tar.gz gcc-6e456a105496a5058ccfdef441678f15de78b893.tar.bz2 |
re PR rtl-optimization/16294 (Missed delay slot scheduling opportunity)
PR rtl-optimization/16294
* resource.c (return_insn_p): New predicate.
(mark_target_live_regs): Use it. Special-case return insns.
(init_resource_info): Use it. Don't scan the epilogue past
a return.
From-SVN: r84874
Diffstat (limited to 'gcc/resource.c')
-rw-r--r-- | gcc/resource.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/gcc/resource.c b/gcc/resource.c index a60e962..a536dd9 100644 --- a/gcc/resource.c +++ b/gcc/resource.c @@ -836,6 +836,20 @@ mark_set_resources (rtx x, struct resources *res, int in_dest, } } +/* Return TRUE if INSN is a return, possibly with a filled delay slot. */ + +static bool +return_insn_p (rtx insn) +{ + if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == RETURN) + return true; + + if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE) + return return_insn_p (XVECEXP (PATTERN (insn), 0, 0)); + + return false; +} + /* Set the resources that are live at TARGET. If TARGET is zero, we refer to the end of the current function and can @@ -894,6 +908,14 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res) return; } + /* Handle return insn. */ + else if (return_insn_p (target)) + { + *res = end_of_function_needs; + mark_referenced_resources (target, res, 0); + return; + } + /* We have to assume memory is needed, but the CC isn't. */ res->memory = 1; res->volatil = res->unch_memory = 0; @@ -1204,8 +1226,12 @@ init_resource_info (rtx epilogue_insn) start_of_epilogue_needs = end_of_function_needs; while ((epilogue_insn = next_nonnote_insn (epilogue_insn))) - mark_set_resources (epilogue_insn, &end_of_function_needs, 0, - MARK_SRC_DEST_CALL); + { + mark_set_resources (epilogue_insn, &end_of_function_needs, 0, + MARK_SRC_DEST_CALL); + if (return_insn_p (epilogue_insn)) + break; + } /* Allocate and initialize the tables used by mark_target_live_regs. */ target_hash_table = xcalloc (TARGET_HASH_PRIME, sizeof (struct target_info *)); |