aboutsummaryrefslogtreecommitdiff
path: root/gcc/reorg.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2011-08-21 11:49:49 -0700
committerRichard Henderson <rth@gcc.gnu.org>2011-08-21 11:49:49 -0700
commit8f06d483ec378303875dbc393e6b112c18604330 (patch)
tree4e15d94c44bd213a7d4ff4743130d7878d558fb3 /gcc/reorg.c
parentb2f7ebc1455ce53ec4d048b85e2fc7d1a94c9e5f (diff)
downloadgcc-8f06d483ec378303875dbc393e6b112c18604330.zip
gcc-8f06d483ec378303875dbc393e6b112c18604330.tar.gz
gcc-8f06d483ec378303875dbc393e6b112c18604330.tar.bz2
rtl.h (INSN_ANNULLED_BRANCH_P): Only allow JUMP_INSN.
* rtl.h (INSN_ANNULLED_BRANCH_P): Only allow JUMP_INSN. * dwarf2cfi.c (scan_trace): Test JUMP_P before INSN_ANNULLED_BRANCH_P. * resource.c (next_insn_no_annul): Likewise. (mark_set_resources): Likewise. * reorg.c (delete_from_delay_slot): Likewise. (dbr_schedule, redundant_insn, try_merge_delay_insns): Likewise. (get_branch_condition): Test pc_rtx and LABEL_REF before dereferencing. From-SVN: r177944
Diffstat (limited to 'gcc/reorg.c')
-rw-r--r--gcc/reorg.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 97d02e9..cf5e7e1 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -667,7 +667,7 @@ delete_from_delay_slot (rtx insn)
annul flag. */
if (delay_list)
trial = emit_delay_sequence (trial, delay_list, XVECLEN (seq, 0) - 2);
- else if (INSN_P (trial))
+ else if (JUMP_P (trial))
INSN_ANNULLED_BRANCH_P (trial) = 0;
INSN_FROM_TARGET_P (insn) = 0;
@@ -1060,13 +1060,15 @@ get_branch_condition (rtx insn, rtx target)
return const_true_rtx;
else if (GET_CODE (src) == IF_THEN_ELSE
- && XEXP (XEXP (src, 1), 0) == target
- && XEXP (src, 2) == pc_rtx)
+ && XEXP (src, 2) == pc_rtx
+ && GET_CODE (XEXP (src, 1)) == LABEL_REF
+ && XEXP (XEXP (src, 1), 0) == target)
return XEXP (src, 0);
else if (GET_CODE (src) == IF_THEN_ELSE
- && XEXP (XEXP (src, 2), 0) == target
- && XEXP (src, 1) == pc_rtx)
+ && XEXP (src, 1) == pc_rtx
+ && GET_CODE (XEXP (src, 2)) == LABEL_REF
+ && XEXP (XEXP (src, 2), 0) == target)
{
enum rtx_code rev;
rev = reversed_comparison_code (XEXP (src, 0), insn);
@@ -1433,7 +1435,7 @@ try_merge_delay_insns (rtx insn, rtx thread)
{
rtx trial, next_trial;
rtx delay_insn = XVECEXP (PATTERN (insn), 0, 0);
- int annul_p = INSN_ANNULLED_BRANCH_P (delay_insn);
+ int annul_p = JUMP_P (delay_insn) && INSN_ANNULLED_BRANCH_P (delay_insn);
int slot_number = 1;
int num_slots = XVECLEN (PATTERN (insn), 0);
rtx next_to_match = XVECEXP (PATTERN (insn), 0, slot_number);
@@ -1517,7 +1519,8 @@ try_merge_delay_insns (rtx insn, rtx thread)
if (slot_number != num_slots
&& trial && NONJUMP_INSN_P (trial)
&& GET_CODE (PATTERN (trial)) == SEQUENCE
- && ! INSN_ANNULLED_BRANCH_P (XVECEXP (PATTERN (trial), 0, 0)))
+ && !(JUMP_P (XVECEXP (PATTERN (trial), 0, 0))
+ && INSN_ANNULLED_BRANCH_P (XVECEXP (PATTERN (trial), 0, 0))))
{
rtx pat = PATTERN (trial);
rtx filled_insn = XVECEXP (pat, 0, 0);
@@ -1756,24 +1759,30 @@ redundant_insn (rtx insn, rtx target, rtx delay_list)
if (GET_CODE (pat) == SEQUENCE)
{
+ bool annul_p = false;
+ rtx control = XVECEXP (pat, 0, 0);
+
/* If this is a CALL_INSN and its delay slots, it is hard to track
the resource needs properly, so give up. */
- if (CALL_P (XVECEXP (pat, 0, 0)))
+ if (CALL_P (control))
return 0;
/* If this is an INSN or JUMP_INSN with delayed effects, it
is hard to track the resource needs properly, so give up. */
#ifdef INSN_SETS_ARE_DELAYED
- if (INSN_SETS_ARE_DELAYED (XVECEXP (pat, 0, 0)))
+ if (INSN_SETS_ARE_DELAYED (control))
return 0;
#endif
#ifdef INSN_REFERENCES_ARE_DELAYED
- if (INSN_REFERENCES_ARE_DELAYED (XVECEXP (pat, 0, 0)))
+ if (INSN_REFERENCES_ARE_DELAYED (control))
return 0;
#endif
+ if (JUMP_P (control))
+ annul_p = INSN_ANNULLED_BRANCH_P (control);
+
/* See if any of the insns in the delay slot match, updating
resource requirements as we go. */
for (i = XVECLEN (pat, 0) - 1; i > 0; i--)
@@ -1783,8 +1792,7 @@ redundant_insn (rtx insn, rtx target, rtx delay_list)
/* If an insn will be annulled if the branch is false, it isn't
considered as a possible duplicate insn. */
if (rtx_equal_p (PATTERN (candidate), ipat)
- && ! (INSN_ANNULLED_BRANCH_P (XVECEXP (pat, 0, 0))
- && INSN_FROM_TARGET_P (candidate)))
+ && ! (annul_p && INSN_FROM_TARGET_P (candidate)))
{
/* Show that this insn will be used in the sequel. */
INSN_FROM_TARGET_P (candidate) = 0;
@@ -1793,15 +1801,14 @@ redundant_insn (rtx insn, rtx target, rtx delay_list)
/* Unless this is an annulled insn from the target of a branch,
we must stop if it sets anything needed or set by INSN. */
- if ((! INSN_ANNULLED_BRANCH_P (XVECEXP (pat, 0, 0))
- || ! INSN_FROM_TARGET_P (candidate))
+ if ((!annul_p || !INSN_FROM_TARGET_P (candidate))
&& insn_sets_resource_p (candidate, &needed, true))
return 0;
}
/* If the insn requiring the delay slot conflicts with INSN, we
must stop. */
- if (insn_sets_resource_p (XVECEXP (pat, 0, 0), &needed, true))
+ if (insn_sets_resource_p (control, &needed, true))
return 0;
}
else
@@ -3867,7 +3874,8 @@ dbr_schedule (rtx first)
{
rtx target;
- INSN_ANNULLED_BRANCH_P (insn) = 0;
+ if (JUMP_P (insn))
+ INSN_ANNULLED_BRANCH_P (insn) = 0;
INSN_FROM_TARGET_P (insn) = 0;
/* Skip vector tables. We can't get attributes for them. */
@@ -3977,10 +3985,12 @@ dbr_schedule (rtx first)
{
if (GET_CODE (PATTERN (insn)) == SEQUENCE)
{
+ rtx control;
j = XVECLEN (PATTERN (insn), 0) - 1;
if (j > MAX_DELAY_HISTOGRAM)
j = MAX_DELAY_HISTOGRAM;
- if (INSN_ANNULLED_BRANCH_P (XVECEXP (PATTERN (insn), 0, 0)))
+ control = XVECEXP (PATTERN (insn), 0, 0);
+ if (JUMP_P (control) && INSN_ANNULLED_BRANCH_P (control))
total_annul_slots[j]++;
else
total_delay_slots[j]++;