mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-30 06:54:37 +08:00
reorg.c (try_merge_delay_insns): Account for resources referenced in each instruction in INSN's delay list...
* reorg.c (try_merge_delay_insns): Account for resources referenced in each instruction in INSN's delay list before trying to eliminate useless instructions. Similarly when looking at a trial insn's delay slots. * reorg.c (check_annul_list_true_false): New function. (steal_delay_list_from_{target,fallthrough}): Call it and also refine tests for when we may annul if already filled a slot. (fill_slots_from_thread): Likewise. (delete_from_delay_slot): Return newly-created thread. (try_merge_delay_isns): Use its new return value. From-SVN: r22685
This commit is contained in:
parent
c5cbf81ecf
commit
96960d10b7
@ -1,3 +1,17 @@
|
||||
Wed Sep 30 18:43:32 1998 Herman ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
|
||||
|
||||
* reorg.c (try_merge_delay_insns): Account for resources referenced
|
||||
in each instruction in INSN's delay list before trying to eliminate
|
||||
useless instructions. Similarly when looking at a trial insn's delay
|
||||
slots.
|
||||
|
||||
* reorg.c (check_annul_list_true_false): New function.
|
||||
(steal_delay_list_from_{target,fallthrough}): Call it and also
|
||||
refine tests for when we may annul if already filled a slot.
|
||||
(fill_slots_from_thread): Likewise.
|
||||
(delete_from_delay_slot): Return newly-created thread.
|
||||
(try_merge_delay_isns): Use its new return value.
|
||||
|
||||
Wed Sep 30 18:29:26 1998 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* loop.c (check_dbra_loop): Use a vanilla loop reversal if the biv is
|
||||
|
99
gcc/reorg.c
99
gcc/reorg.c
@ -234,7 +234,7 @@ static int insn_sets_resource_p PROTO((rtx, struct resources *, int));
|
||||
static rtx find_end_label PROTO((void));
|
||||
static rtx emit_delay_sequence PROTO((rtx, rtx, int));
|
||||
static rtx add_to_delay_list PROTO((rtx, rtx));
|
||||
static void delete_from_delay_slot PROTO((rtx));
|
||||
static rtx delete_from_delay_slot PROTO((rtx));
|
||||
static void delete_scheduled_jump PROTO((rtx));
|
||||
static void note_delay_statistics PROTO((int, int));
|
||||
static rtx optimize_skip PROTO((rtx));
|
||||
@ -1011,7 +1011,7 @@ add_to_delay_list (insn, delay_list)
|
||||
/* Delete INSN from the delay slot of the insn that it is in. This may
|
||||
produce an insn without anything in its delay slots. */
|
||||
|
||||
static void
|
||||
static rtx
|
||||
delete_from_delay_slot (insn)
|
||||
rtx insn;
|
||||
{
|
||||
@ -1060,6 +1060,8 @@ delete_from_delay_slot (insn)
|
||||
|
||||
/* Show we need to fill this insn again. */
|
||||
obstack_ptr_grow (&unfilled_slots_obstack, trial);
|
||||
|
||||
return trial;
|
||||
}
|
||||
|
||||
/* Delete INSN, a JUMP_INSN. If it is a conditional jump, we must track down
|
||||
@ -1624,6 +1626,31 @@ redirect_with_delay_list_safe_p (jump, newlabel, delay_list)
|
||||
return (li == NULL);
|
||||
}
|
||||
|
||||
/* DELAY_LIST is a list of insns that have already been placed into delay
|
||||
slots. See if all of them have the same annulling status as ANNUL_TRUE_P.
|
||||
If not, return 0; otherwise return 1. */
|
||||
|
||||
static int
|
||||
check_annul_list_true_false (annul_true_p, delay_list)
|
||||
int annul_true_p;
|
||||
rtx delay_list;
|
||||
{
|
||||
rtx temp, trial;
|
||||
|
||||
if (delay_list)
|
||||
{
|
||||
for (temp = delay_list; temp; temp = XEXP (temp, 1))
|
||||
{
|
||||
rtx trial = XEXP (temp, 0);
|
||||
|
||||
if ((annul_true_p && INSN_FROM_TARGET_P (trial))
|
||||
|| (!annul_true_p && !INSN_FROM_TARGET_P (trial)))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* INSN branches to an insn whose pattern SEQ is a SEQUENCE. Given that
|
||||
the condition tested by INSN is CONDITION and the resources shown in
|
||||
@ -1714,9 +1741,15 @@ steal_delay_list_from_target (insn, condition, seq, delay_list,
|
||||
|| (! insn_sets_resource_p (trial, other_needed, 0)
|
||||
&& ! may_trap_p (PATTERN (trial)))))
|
||||
? eligible_for_delay (insn, total_slots_filled, trial, flags)
|
||||
: (must_annul = 1,
|
||||
eligible_for_annul_false (insn, total_slots_filled, trial, flags)))
|
||||
: (must_annul || (delay_list == NULL && new_delay_list == NULL))
|
||||
&& (must_annul = 1,
|
||||
check_annul_list_true_false (0, delay_list)
|
||||
&& check_annul_list_true_false (0, new_delay_list)
|
||||
&& eligible_for_annul_false (insn, total_slots_filled,
|
||||
trial, flags)))
|
||||
{
|
||||
if (must_annul)
|
||||
used_annul = 1;
|
||||
temp = copy_rtx (trial);
|
||||
INSN_FROM_TARGET_P (temp) = 1;
|
||||
new_delay_list = add_to_delay_list (temp, new_delay_list);
|
||||
@ -1735,7 +1768,8 @@ steal_delay_list_from_target (insn, condition, seq, delay_list,
|
||||
/* Add any new insns to the delay list and update the count of the
|
||||
number of slots filled. */
|
||||
*pslots_filled = total_slots_filled;
|
||||
*pannul_p = must_annul;
|
||||
if (used_annul)
|
||||
*pannul_p = 1;
|
||||
|
||||
if (delay_list == 0)
|
||||
return new_delay_list;
|
||||
@ -1765,6 +1799,8 @@ steal_delay_list_from_fallthrough (insn, condition, seq,
|
||||
{
|
||||
int i;
|
||||
int flags;
|
||||
int must_annul = *pannul_p;
|
||||
int used_annul = 0;
|
||||
|
||||
flags = get_jump_flags (insn, JUMP_LABEL (insn));
|
||||
|
||||
@ -1798,14 +1834,17 @@ steal_delay_list_from_fallthrough (insn, condition, seq,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! *pannul_p
|
||||
if (! must_annul
|
||||
&& ((condition == const_true_rtx
|
||||
|| (! insn_sets_resource_p (trial, other_needed, 0)
|
||||
&& ! may_trap_p (PATTERN (trial)))))
|
||||
? eligible_for_delay (insn, *pslots_filled, trial, flags)
|
||||
: (*pannul_p = 1,
|
||||
eligible_for_annul_true (insn, *pslots_filled, trial, flags)))
|
||||
: (must_annul || delay_list == NULL) && (must_annul = 1,
|
||||
check_annul_list_true_false (1, delay_list)
|
||||
&& eligible_for_annul_true (insn, *pslots_filled, trial, flags)))
|
||||
{
|
||||
if (must_annul)
|
||||
used_annul = 1;
|
||||
delete_from_delay_slot (trial);
|
||||
delay_list = add_to_delay_list (trial, delay_list);
|
||||
|
||||
@ -1816,8 +1855,11 @@ steal_delay_list_from_fallthrough (insn, condition, seq,
|
||||
break;
|
||||
}
|
||||
|
||||
if (used_annul)
|
||||
*pannul_p = 1;
|
||||
return delay_list;
|
||||
}
|
||||
|
||||
|
||||
/* Try merging insns starting at THREAD which match exactly the insns in
|
||||
INSN's delay list.
|
||||
@ -1849,13 +1891,15 @@ try_merge_delay_insns (insn, thread)
|
||||
CLEAR_RESOURCE (&set);
|
||||
|
||||
/* If this is not an annulling branch, take into account anything needed in
|
||||
NEXT_TO_MATCH. This prevents two increments from being incorrectly
|
||||
INSN's delay slot. This prevents two increments from being incorrectly
|
||||
folded into one. If we are annulling, this would be the correct
|
||||
thing to do. (The alternative, looking at things set in NEXT_TO_MATCH
|
||||
will essentially disable this optimization. This method is somewhat of
|
||||
a kludge, but I don't see a better way.) */
|
||||
if (! annul_p)
|
||||
mark_referenced_resources (next_to_match, &needed, 1);
|
||||
for (i = 1 ; i < num_slots ; i++)
|
||||
if (XVECEXP (PATTERN (insn), 0, i))
|
||||
mark_referenced_resources (XVECEXP (PATTERN (insn), 0, i), &needed, 1);
|
||||
|
||||
for (trial = thread; !stop_search_p (trial, 1); trial = next_trial)
|
||||
{
|
||||
@ -1904,8 +1948,6 @@ try_merge_delay_insns (insn, thread)
|
||||
break;
|
||||
|
||||
next_to_match = XVECEXP (PATTERN (insn), 0, slot_number);
|
||||
if (! annul_p)
|
||||
mark_referenced_resources (next_to_match, &needed, 1);
|
||||
}
|
||||
|
||||
mark_set_resources (trial, &set, 0, 1);
|
||||
@ -1941,8 +1983,12 @@ try_merge_delay_insns (insn, thread)
|
||||
{
|
||||
if (! annul_p)
|
||||
{
|
||||
rtx new;
|
||||
|
||||
update_block (dtrial, thread);
|
||||
delete_from_delay_slot (dtrial);
|
||||
new = delete_from_delay_slot (dtrial);
|
||||
if (INSN_DELETED_P (thread))
|
||||
thread = new;
|
||||
INSN_FROM_TARGET_P (next_to_match) = 0;
|
||||
}
|
||||
else
|
||||
@ -1954,6 +2000,12 @@ try_merge_delay_insns (insn, thread)
|
||||
|
||||
next_to_match = XVECEXP (PATTERN (insn), 0, slot_number);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Keep track of the set/referenced resources for
|
||||
mark_set_resources (dtrial, &set, 0, 1);
|
||||
mark_referenced_resources (dtrial, &needed, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1968,8 +2020,12 @@ try_merge_delay_insns (insn, thread)
|
||||
{
|
||||
if (GET_MODE (merged_insns) == SImode)
|
||||
{
|
||||
rtx new;
|
||||
|
||||
update_block (XEXP (merged_insns, 0), thread);
|
||||
delete_from_delay_slot (XEXP (merged_insns, 0));
|
||||
new = delete_from_delay_slot (XEXP (merged_insns, 0));
|
||||
if (INSN_DELETED_P (thread))
|
||||
thread = new;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3600,9 +3656,10 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
|
||||
/* There are two ways we can win: If TRIAL doesn't set anything
|
||||
needed at the opposite thread and can't trap, or if it can
|
||||
go into an annulled delay slot. */
|
||||
if (condition == const_true_rtx
|
||||
|| (! insn_sets_resource_p (trial, &opposite_needed, 1)
|
||||
&& ! may_trap_p (pat)))
|
||||
if (!must_annul
|
||||
&& (condition == const_true_rtx
|
||||
|| (! insn_sets_resource_p (trial, &opposite_needed, 1)
|
||||
&& ! may_trap_p (pat))))
|
||||
{
|
||||
old_trial = trial;
|
||||
trial = try_split (pat, trial, 0);
|
||||
@ -3630,9 +3687,11 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
|
||||
if (thread == old_trial)
|
||||
thread = trial;
|
||||
pat = PATTERN (trial);
|
||||
if ((thread_if_true
|
||||
? eligible_for_annul_false (insn, *pslots_filled, trial, flags)
|
||||
: eligible_for_annul_true (insn, *pslots_filled, trial, flags)))
|
||||
if ((must_annul || delay_list == NULL) && (thread_if_true
|
||||
? check_annul_list_true_false (0, delay_list)
|
||||
&& eligible_for_annul_false (insn, *pslots_filled, trial, flags)
|
||||
: check_annul_list_true_false (1, delay_list)
|
||||
&& eligible_for_annul_true (insn, *pslots_filled, trial, flags)))
|
||||
{
|
||||
rtx temp;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user