#define SUBST_MODE(INTO, NEWVAL) do_SUBST_MODE(&(INTO), (NEWVAL))
\f
/* Subroutine of try_combine. Determine whether the combine replacement
- patterns NEWPAT and NEWI2PAT are cheaper according to insn_rtx_cost
- that the original instruction sequence I1, I2 and I3. Note that I1
- and/or NEWI2PAT may be NULL_RTX. This function returns false, if the
- costs of all instructions can be estimated, and the replacements are
- more expensive than the original sequence. */
+ patterns NEWPAT, NEWI2PAT and NEWOTHERPAT are cheaper according to
+ insn_rtx_cost that the original instruction sequence I1, I2, I3 and
+ undobuf.other_insn. Note that I1 and/or NEWI2PAT may be NULL_RTX.
+ NEWOTHERPAT and undobuf.other_insn may also both be NULL_RTX. This
+ function returns false, if the costs of all instructions can be
+ estimated, and the replacements are more expensive than the original
+ sequence. */
static bool
-combine_validate_cost (rtx i1, rtx i2, rtx i3, rtx newpat, rtx newi2pat)
+combine_validate_cost (rtx i1, rtx i2, rtx i3, rtx newpat, rtx newi2pat,
+ rtx newotherpat)
{
int i1_cost, i2_cost, i3_cost;
int new_i2_cost, new_i3_cost;
int old_other_cost, new_other_cost;
old_other_cost = INSN_COST (undobuf.other_insn);
- new_other_cost = insn_rtx_cost (PATTERN (undobuf.other_insn));
+ new_other_cost = insn_rtx_cost (newotherpat);
if (old_other_cost > 0 && new_other_cost > 0)
{
old_cost += old_other_cost;
of an insn just above it. Call distribute_links to make a LOG_LINK from
the next use of that destination. */
distribute_links (gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX));
+
+ df_insn_rescan (insn);
}
/* Return TRUE if combine can reuse reg X in mode MODE.
int maxreg;
rtx temp;
rtx link;
+ rtx other_pat = 0;
+ rtx new_other_notes;
int i;
/* Exit early if one of the insns involved can't be used for
/* If we had to change another insn, make sure it is valid also. */
if (undobuf.other_insn)
{
- rtx other_pat = PATTERN (undobuf.other_insn);
- rtx new_other_notes;
- rtx note, next;
-
CLEAR_HARD_REG_SET (newpat_used_regs);
+ other_pat = PATTERN (undobuf.other_insn);
other_code_number = recog_for_combine (&other_pat, undobuf.other_insn,
&new_other_notes);
undo_all ();
return 0;
}
-
- PATTERN (undobuf.other_insn) = other_pat;
-
- /* If any of the notes in OTHER_INSN were REG_UNUSED, ensure that they
- are still valid. Then add any non-duplicate notes added by
- recog_for_combine. */
- for (note = REG_NOTES (undobuf.other_insn); note; note = next)
- {
- next = XEXP (note, 1);
-
- if (REG_NOTE_KIND (note) == REG_UNUSED
- && ! reg_set_p (XEXP (note, 0), PATTERN (undobuf.other_insn)))
- remove_note (undobuf.other_insn, note);
- }
-
- distribute_notes (new_other_notes, undobuf.other_insn,
- undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX);
}
+
#ifdef HAVE_cc0
/* If I2 is the CC0 setter and I3 is the CC0 user then check whether
they are adjacent to each other or not. */
/* Only allow this combination if insn_rtx_costs reports that the
replacement instructions are cheaper than the originals. */
- if (!combine_validate_cost (i1, i2, i3, newpat, newi2pat))
+ if (!combine_validate_cost (i1, i2, i3, newpat, newi2pat, other_pat))
{
undo_all ();
return 0;
/* We now know that we can do this combination. Merge the insns and
update the status of registers and LOG_LINKS. */
+ if (undobuf.other_insn)
+ {
+ rtx note, next;
+
+ PATTERN (undobuf.other_insn) = other_pat;
+
+ /* If any of the notes in OTHER_INSN were REG_UNUSED, ensure that they
+ are still valid. Then add any non-duplicate notes added by
+ recog_for_combine. */
+ for (note = REG_NOTES (undobuf.other_insn); note; note = next)
+ {
+ next = XEXP (note, 1);
+
+ if (REG_NOTE_KIND (note) == REG_UNUSED
+ && ! reg_set_p (XEXP (note, 0), PATTERN (undobuf.other_insn)))
+ remove_note (undobuf.other_insn, note);
+ }
+
+ distribute_notes (new_other_notes, undobuf.other_insn,
+ undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX);
+ }
+
if (swap_i2i3)
{
rtx insn;
REG_NOTES (insn) = 0;
insn_code_number = recog (pat, insn, &num_clobbers_to_add);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ if (insn_code_number < 0)
+ fputs ("Failed to match this instruction:\n", dump_file);
+ else
+ fputs ("Successfully matched this instruction:\n", dump_file);
+ print_rtl_single (dump_file, pat);
+ }
/* If it isn't, there is the possibility that we previously had an insn
that clobbered some register as a side effect, but the combined
PATTERN (insn) = pat;
insn_code_number = recog (pat, insn, &num_clobbers_to_add);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ if (insn_code_number < 0)
+ fputs ("Failed to match this instruction:\n", dump_file);
+ else
+ fputs ("Successfully matched this instruction:\n", dump_file);
+ print_rtl_single (dump_file, pat);
+ }
}
PATTERN (insn) = old_pat;
REG_NOTES (insn) = old_notes;