summaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorrask <rask@138bc75d-0d04-0410-961f-82ee72b054a4>2007-06-30 11:28:57 +0000
committerrask <rask@138bc75d-0d04-0410-961f-82ee72b054a4>2007-06-30 11:28:57 +0000
commit06a8a63d09b62250b61cab7509c345e4b52b6951 (patch)
treebe2b2c854a34ecde6efefc3a98395e98106b9a6a /gcc/combine.c
parentffbd194b988865c76cfe0b743b88bbdd49e5a391 (diff)
downloadgcc-06a8a63d09b62250b61cab7509c345e4b52b6951.tar.gz
* combine.c (combine_validate_cost): New parameter NEWOTHERPAT.
(try_combine): Move potential calls to undo_all() so they happen before we commit to using the combined insns. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@126142 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c66
1 files changed, 37 insertions, 29 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index fece7e02614..5cf65bae192 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -741,14 +741,17 @@ do_SUBST_MODE (rtx *into, enum machine_mode newval)
#define SUBST_MODE(INTO, NEWVAL) do_SUBST_MODE(&(INTO), (NEWVAL))
/* 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;
@@ -789,7 +792,7 @@ combine_validate_cost (rtx i1, rtx i2, rtx i3, rtx newpat, rtx newi2pat)
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;
@@ -2159,6 +2162,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
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
@@ -3285,12 +3290,9 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
/* 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);
@@ -3299,24 +3301,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
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. */
@@ -3333,7 +3319,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
/* 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;
@@ -3342,6 +3328,28 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
/* 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;