{
rtx arg0 = va_arg (p, rtx);
- hashcode = (code + RTL_HASH (arg0));
+ hashcode = ((int) code + RTL_HASH (arg0));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
if (h->hashcode == hashcode
&& GET_CODE (h->u.rtl) == code
rtx arg0 = va_arg (p, rtx);
rtx arg1 = va_arg (p, rtx);
- hashcode = (code + RTL_HASH (arg0) + RTL_HASH (arg1));
+ hashcode = ((int) code + RTL_HASH (arg0) + RTL_HASH (arg1));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
if (h->hashcode == hashcode
&& GET_CODE (h->u.rtl) == code
{
char * arg0 = va_arg (p, char *);
- hashcode = (code + RTL_HASH (arg0));
+ hashcode = ((int) code + RTL_HASH (arg0));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
if (h->hashcode == hashcode
&& GET_CODE (h->u.rtl) == code
char * arg0 = va_arg (p, char *);
char * arg1 = va_arg (p, char *);
- hashcode = (code + RTL_HASH (arg0) + RTL_HASH (arg1));
+ hashcode = ((int) code + RTL_HASH (arg0) + RTL_HASH (arg1));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
if (h->hashcode == hashcode
&& GET_CODE (h->u.rtl) == code
an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
note with an operand of EQUIV.
+ Moving assignments to pseudos outside of the block is done to improve
+ the generated code, but is not required to generate correct code,
+ hence being unable to move an assignment is not grounds for not making
+ a libcall block. There are two reasons why it is safe to leave these
+ insns inside the block: First, we know that these pseudos cannot be
+ used in generated RTL outside the block since they are created for
+ temporary purposes within the block. Second, CSE will not record the
+ values of anything set inside a libcall block, so we know they must
+ be dead at the end of the block.
+
Except for the first group of insns (the ones setting pseudos), the
block is delimited by REG_RETVAL and REG_LIBCALL notes. */
rtx prev, next, first, last, insn;
/* First emit all insns that set pseudos. Remove them from the list as
- we go. */
+ we go. Avoid insns that set pseudo which were referenced in previous
+ insns. These can be generated by move_by_pieces, for example,
+ to update an address. */
for (insn = insns; insn; insn = next)
{
next = NEXT_INSN (insn);
if (set != 0 && GET_CODE (SET_DEST (set)) == REG
- && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
+ && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
+ && ! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
+ && ! reg_used_between_p (SET_DEST (set), insns, insn))
{
if (PREV_INSN (insn))
NEXT_INSN (PREV_INSN (insn)) = next;