aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-06-08 14:24:30 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-06-08 12:24:30 +0000
commitcf7ec0ab009db4a5cda12d0756427bd6d292e377 (patch)
treeb697dc90e12964767994ab80553cb5edacea3c88 /gcc
parentd58d4c12b026c142675eaac6e56b39a6ee19a267 (diff)
downloadgcc-cf7ec0ab009db4a5cda12d0756427bd6d292e377.zip
gcc-cf7ec0ab009db4a5cda12d0756427bd6d292e377.tar.gz
gcc-cf7ec0ab009db4a5cda12d0756427bd6d292e377.tar.bz2
sibcall.c (skip_unreturned_value): New function.
* sibcall.c (skip_unreturned_value): New function. (call_ends_block_p): Use it. From-SVN: r43010
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog3
-rw-r--r--gcc/sibcall.c35
2 files changed, 38 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 45f1eb2..05be51c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,8 @@
Fri Jun 8 14:16:33 CEST 2001 Jan Hubicka <jh@suse.cz>
+ * sibcall.c (skip_unreturned_value): New function.
+ (call_ends_block_p): Use it.
+
* recog.c (split_insn): Break out from ...
(split_all_insns): ... here; do not use basic block information
when it is broken.
diff --git a/gcc/sibcall.c b/gcc/sibcall.c
index eefe080..5c437b1 100644
--- a/gcc/sibcall.c
+++ b/gcc/sibcall.c
@@ -43,6 +43,7 @@ static int uses_addressof PARAMS ((rtx));
static int sequence_uses_addressof PARAMS ((rtx));
static void purge_reg_equiv_notes PARAMS ((void));
static void purge_mem_unchanging_flag PARAMS ((rtx));
+static rtx skip_unreturned_value PARAMS ((rtx));
/* Examine a CALL_PLACEHOLDER pattern and determine where the call's
return value is located. P_HARD_RETURN receives the hard register
@@ -220,6 +221,35 @@ skip_use_of_return_value (orig_insn, code)
return orig_insn;
}
+/* In case function does not return value, we get clobber of pseudo followed
+ by set to hard return value. */
+static rtx
+skip_unreturned_value (orig_insn)
+ rtx orig_insn;
+{
+ rtx insn = next_nonnote_insn (orig_insn);
+
+ /* Skip possible clobber of pseudo return register. */
+ if (insn
+ && GET_CODE (insn) == INSN
+ && GET_CODE (PATTERN (insn)) == CLOBBER
+ && REG_P (XEXP (PATTERN (insn), 0))
+ && (REGNO (XEXP (PATTERN (insn), 0)) >= FIRST_PSEUDO_REGISTER))
+ {
+ rtx set_insn = next_nonnote_insn (insn);
+ rtx set;
+ if (!set_insn)
+ return insn;
+ set = single_set (set_insn);
+ if (!set
+ || SET_SRC (set) != XEXP (PATTERN (insn), 0)
+ || SET_DEST (set) != current_function_return_rtx)
+ return insn;
+ return set_insn;
+ }
+ return orig_insn;
+}
+
/* If the first real insn after ORIG_INSN adjusts the stack pointer
by a constant, return the insn with the stack pointer adjustment.
Otherwise return ORIG_INSN. */
@@ -317,6 +347,11 @@ call_ends_block_p (insn, end)
if (insn == end)
return 1;
+ /* Skip over a CLOBBER of the return value as a hard reg. */
+ insn = skip_unreturned_value (insn);
+ if (insn == end)
+ return 1;
+
/* Skip over a USE of the return value (as a hard reg). */
insn = skip_use_of_return_value (insn, USE);
if (insn == end)