summaryrefslogtreecommitdiff
path: root/gcc/sibcall.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-06-08 12:24:30 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-06-08 12:24:30 +0000
commitf9dc5b3b7158940b6c8524b35ba092045ca5f156 (patch)
treeb697dc90e12964767994ab80553cb5edacea3c88 /gcc/sibcall.c
parent3a2624cfdcc147388231db352afc5f28f74f64ac (diff)
downloadgcc-f9dc5b3b7158940b6c8524b35ba092045ca5f156.tar.gz
* sibcall.c (skip_unreturned_value): New function.
(call_ends_block_p): Use it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@43010 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/sibcall.c')
-rw-r--r--gcc/sibcall.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/gcc/sibcall.c b/gcc/sibcall.c
index eefe0809eec..5c437b10539 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)