summaryrefslogtreecommitdiff
path: root/gcc/resource.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-17 18:12:37 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-17 18:12:37 +0000
commit3657db9e26c64e1f1867d874d4defd52a320e37d (patch)
tree644d0f4f5e087fec3c389cf35c1c4cc29f74be50 /gcc/resource.c
parent0e1a77e12832a15c920e5a95b83747d7020b03bd (diff)
downloadgcc-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.c30
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 *));