rtl.h (set_for_reg_notes): Declare.

2014-05-26  Richard Sandiford  <rdsandiford@googlemail.com>
            Olivier Hainque  <hainque@adacore.com>

        * rtl.h (set_for_reg_notes): Declare.
        * emit-rtl.c (set_for_reg_notes): New function.
        (set_unique_reg_note): Use it.
        * optabs.c (add_equal_note): Likewise


Co-Authored-By: Olivier Hainque <hainque@adacore.com>

From-SVN: r210998
This commit is contained in:
Richard Sandiford 2014-05-28 08:41:27 +00:00 committed by Olivier Hainque
parent 9c6ab05f6a
commit c8912e539b
4 changed files with 60 additions and 25 deletions

View File

@ -1,3 +1,11 @@
2014-05-26 Richard Sandiford <rdsandiford@googlemail.com>
Olivier Hainque <hainque@adacore.com>
* rtl.h (set_for_reg_notes): Declare.
* emit-rtl.c (set_for_reg_notes): New function.
(set_unique_reg_note): Use it.
* optabs.c (add_equal_note): Likewise
2014-05-22 Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org> 2014-05-22 Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
* MAINTAINERS: Update my affiliation/email. * MAINTAINERS: Update my affiliation/email.

View File

@ -5086,6 +5086,45 @@ gen_use (rtx x)
return seq; return seq;
} }
/* Notes like REG_EQUAL and REG_EQUIV refer to a set in an instruction.
Return the set in INSN that such notes describe, or NULL if the notes
have no meaning for INSN. */
rtx
set_for_reg_notes (rtx insn)
{
rtx pat, reg;
if (!INSN_P (insn))
return NULL_RTX;
pat = PATTERN (insn);
if (GET_CODE (pat) == PARALLEL)
{
/* We do not use single_set because that ignores SETs of unused
registers. REG_EQUAL and REG_EQUIV notes really do require the
PARALLEL to have a single SET. */
if (multiple_sets (insn))
return NULL_RTX;
pat = XVECEXP (pat, 0, 0);
}
if (GET_CODE (pat) != SET)
return NULL_RTX;
reg = SET_DEST (pat);
/* Notes apply to the contents of a STRICT_LOW_PART. */
if (GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
/* Check that we have a register. */
if (!(REG_P (reg) || GET_CODE (reg) == SUBREG))
return NULL_RTX;
return pat;
}
/* Place a note of KIND on insn INSN with DATUM as the datum. If a /* Place a note of KIND on insn INSN with DATUM as the datum. If a
note of this type already exists, remove it first. */ note of this type already exists, remove it first. */
@ -5098,39 +5137,26 @@ set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
{ {
case REG_EQUAL: case REG_EQUAL:
case REG_EQUIV: case REG_EQUIV:
/* Don't add REG_EQUAL/REG_EQUIV notes if the insn if (!set_for_reg_notes (insn))
has multiple sets (some callers assume single_set return NULL_RTX;
means the insn only has one set, when in fact it
means the insn only has one * useful * set). */
if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
{
gcc_assert (!note);
return NULL_RTX;
}
/* Don't add ASM_OPERAND REG_EQUAL/REG_EQUIV notes. /* Don't add ASM_OPERAND REG_EQUAL/REG_EQUIV notes.
It serves no useful purpose and breaks eliminate_regs. */ It serves no useful purpose and breaks eliminate_regs. */
if (GET_CODE (datum) == ASM_OPERANDS) if (GET_CODE (datum) == ASM_OPERANDS)
return NULL_RTX; return NULL_RTX;
if (note)
{
XEXP (note, 0) = datum;
df_notes_rescan (insn);
return note;
}
break; break;
default: default:
if (note)
{
XEXP (note, 0) = datum;
return note;
}
break; break;
} }
add_reg_note (insn, kind, datum); if (note)
XEXP (note, 0) = datum;
else
{
add_reg_note (insn, kind, datum);
note = REG_NOTES (insn);
}
switch (kind) switch (kind)
{ {
@ -5142,14 +5168,14 @@ set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
break; break;
} }
return REG_NOTES (insn); return note;
} }
/* Like set_unique_reg_note, but don't do anything unless INSN sets DST. */ /* Like set_unique_reg_note, but don't do anything unless INSN sets DST. */
rtx rtx
set_dst_reg_note (rtx insn, enum reg_note kind, rtx datum, rtx dst) set_dst_reg_note (rtx insn, enum reg_note kind, rtx datum, rtx dst)
{ {
rtx set = single_set (insn); rtx set = set_for_reg_notes (insn);
if (set && SET_DEST (set) == dst) if (set && SET_DEST (set) == dst)
return set_unique_reg_note (insn, kind, datum); return set_unique_reg_note (insn, kind, datum);

View File

@ -228,7 +228,7 @@ add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
return 0; return 0;
} }
set = single_set (last_insn); set = set_for_reg_notes (last_insn);
if (set == NULL_RTX) if (set == NULL_RTX)
return 1; return 1;

View File

@ -2197,6 +2197,7 @@ extern enum machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
bool); bool);
/* In emit-rtl.c */ /* In emit-rtl.c */
extern rtx set_for_reg_notes (rtx);
extern rtx set_unique_reg_note (rtx, enum reg_note, rtx); extern rtx set_unique_reg_note (rtx, enum reg_note, rtx);
extern rtx set_dst_reg_note (rtx, enum reg_note, rtx, rtx); extern rtx set_dst_reg_note (rtx, enum reg_note, rtx, rtx);
extern void set_insn_deleted (rtx); extern void set_insn_deleted (rtx);