Commit 5317d2f8 by Richard Kenner

(redundant_insn_p): Change return type to rtx.

(redundant_insn_p): Change return type to rtx.  Return the redundant insn
instead of true.
(update_reg_unused_notes): New function.
(fill_slots_from_thread): Call update_reg_unused_notes after one of the
redundant_insn_p calls.

From-SVN: r8446
parent e3149275
...@@ -244,12 +244,13 @@ static rtx steal_delay_list_from_fallthrough PROTO((rtx, rtx, rtx, rtx, ...@@ -244,12 +244,13 @@ static rtx steal_delay_list_from_fallthrough PROTO((rtx, rtx, rtx, rtx,
struct resources *, struct resources *,
int, int *, int *)); int, int *, int *));
static void try_merge_delay_insns PROTO((rtx, rtx)); static void try_merge_delay_insns PROTO((rtx, rtx));
static int redundant_insn_p PROTO((rtx, rtx, rtx)); static rtx redundant_insn_p PROTO((rtx, rtx, rtx));
static int own_thread_p PROTO((rtx, rtx, int)); static int own_thread_p PROTO((rtx, rtx, int));
static int find_basic_block PROTO((rtx)); static int find_basic_block PROTO((rtx));
static void update_block PROTO((rtx, rtx)); static void update_block PROTO((rtx, rtx));
static int reorg_redirect_jump PROTO((rtx, rtx)); static int reorg_redirect_jump PROTO((rtx, rtx));
static void update_reg_dead_notes PROTO((rtx, rtx)); static void update_reg_dead_notes PROTO((rtx, rtx));
static void update_reg_unused_notes PROTO((rtx, rtx));
static void update_live_status PROTO((rtx, rtx)); static void update_live_status PROTO((rtx, rtx));
static rtx next_insn_no_annul PROTO((rtx)); static rtx next_insn_no_annul PROTO((rtx));
static void mark_target_live_regs PROTO((rtx, struct resources *)); static void mark_target_live_regs PROTO((rtx, struct resources *));
...@@ -1922,7 +1923,7 @@ try_merge_delay_insns (insn, thread) ...@@ -1922,7 +1923,7 @@ try_merge_delay_insns (insn, thread)
redundant insn, but the cost of splitting seems greater than the possible redundant insn, but the cost of splitting seems greater than the possible
gain in rare cases. */ gain in rare cases. */
static int static rtx
redundant_insn_p (insn, target, delay_list) redundant_insn_p (insn, target, delay_list)
rtx insn; rtx insn;
rtx target; rtx target;
...@@ -2079,7 +2080,7 @@ redundant_insn_p (insn, target, delay_list) ...@@ -2079,7 +2080,7 @@ redundant_insn_p (insn, target, delay_list)
{ {
/* Show that this insn will be used in the sequel. */ /* Show that this insn will be used in the sequel. */
INSN_FROM_TARGET_P (candidate) = 0; INSN_FROM_TARGET_P (candidate) = 0;
return 1; return candidate;
} }
/* Unless this is an annulled insn from the target of a branch, /* Unless this is an annulled insn from the target of a branch,
...@@ -2101,7 +2102,7 @@ redundant_insn_p (insn, target, delay_list) ...@@ -2101,7 +2102,7 @@ redundant_insn_p (insn, target, delay_list)
/* See if TRIAL is the same as INSN. */ /* See if TRIAL is the same as INSN. */
pat = PATTERN (trial); pat = PATTERN (trial);
if (rtx_equal_p (pat, ipat)) if (rtx_equal_p (pat, ipat))
return 1; return trial;
/* Can't go any further if TRIAL conflicts with INSN. */ /* Can't go any further if TRIAL conflicts with INSN. */
if (insn_sets_resource_p (trial, &needed, 1)) if (insn_sets_resource_p (trial, &needed, 1))
...@@ -2277,6 +2278,33 @@ update_reg_dead_notes (insn, delayed_insn) ...@@ -2277,6 +2278,33 @@ update_reg_dead_notes (insn, delayed_insn)
} }
} }
/* Delete any REG_UNUSED notes that exist on INSN but not on REDUNDANT_INSN.
This handles the case of udivmodXi4 instructions which optimize their
output depending on whether any REG_UNUSED notes are present.
we must make sure that INSN calculates as many results as REDUNDANT_INSN
does. */
static void
update_reg_unused_notes (insn, redundant_insn)
rtx insn, redundant_insn;
{
rtx p, link, next;
for (link = REG_NOTES (insn); link; link = next)
{
next = XEXP (link, 1);
if (REG_NOTE_KIND (link) != REG_UNUSED
|| GET_CODE (XEXP (link, 0)) != REG)
continue;
if (! find_regno_note (redundant_insn, REG_UNUSED,
REGNO (XEXP (link, 0))))
remove_note (insn, link);
}
}
/* Marks registers possibly live at the current place being scanned by /* Marks registers possibly live at the current place being scanned by
mark_target_live_regs. Used only by next two function. */ mark_target_live_regs. Used only by next two function. */
...@@ -3279,10 +3307,12 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely, ...@@ -3279,10 +3307,12 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
#endif #endif
) )
{ {
rtx prior_insn;
/* If TRIAL is redundant with some insn before INSN, we don't /* If TRIAL is redundant with some insn before INSN, we don't
actually need to add it to the delay list; we can merely pretend actually need to add it to the delay list; we can merely pretend
we did. */ we did. */
if (redundant_insn_p (trial, insn, delay_list)) if (prior_insn = redundant_insn_p (trial, insn, delay_list))
{ {
if (own_thread) if (own_thread)
{ {
...@@ -3297,7 +3327,10 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely, ...@@ -3297,7 +3327,10 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
delete_insn (trial); delete_insn (trial);
} }
else else
{
update_reg_unused_notes (prior_insn, trial);
new_thread = next_active_insn (trial); new_thread = next_active_insn (trial);
}
continue; continue;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment