diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-17 18:12:37 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-17 18:12:37 +0000 |
commit | 3657db9e26c64e1f1867d874d4defd52a320e37d (patch) | |
tree | 644d0f4f5e087fec3c389cf35c1c4cc29f74be50 /gcc/resource.c | |
parent | 0e1a77e12832a15c920e5a95b83747d7020b03bd (diff) | |
download | gcc-3657db9e26c64e1f1867d874d4defd52a320e37d.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@84874 138bc75d-0d04-0410-961f-82ee72b054a4
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 a60e96296f3..a536dd905a7 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 *)); |