Commit 3480bb98 by Jeff Law

jump.c (condjump_in_parallel_p): New function to detect conditional jumps within PARALLEL insns.

        * jump.c (condjump_in_parallel_p): New function to detect
        conditional jumps within PARALLEL insns.
        (jump_optimize): Allow for some simple optimizations involving
        conditional jumps within PARALLEL insns.
        * reorg.c (get_jump_flags): Handle conditional jumps in PARALLEL
        insns.
        (get_branch_condition, fill_simple_delay_slots): Likewise.
        (fill_eager_delay_slots, relax_delay_slots, dbr_schedule): Likewise.

From-SVN: r7452
parent 36e2f858
...@@ -566,6 +566,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -566,6 +566,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
rtx temp, temp1, temp2, temp3, temp4, temp5, temp6; rtx temp, temp1, temp2, temp3, temp4, temp5, temp6;
rtx nlabel; rtx nlabel;
int this_is_simplejump, this_is_condjump, reversep; int this_is_simplejump, this_is_condjump, reversep;
int this_is_condjump_in_parallel;
#if 0 #if 0
/* If NOT the first iteration, if this is the last jump pass /* If NOT the first iteration, if this is the last jump pass
(just before final), do the special peephole optimizations. (just before final), do the special peephole optimizations.
...@@ -605,6 +606,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -605,6 +606,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
this_is_simplejump = simplejump_p (insn); this_is_simplejump = simplejump_p (insn);
this_is_condjump = condjump_p (insn); this_is_condjump = condjump_p (insn);
this_is_condjump_in_parallel = condjump_in_parallel_p (insn);
/* Tension the labels in dispatch tables. */ /* Tension the labels in dispatch tables. */
...@@ -1644,7 +1646,8 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -1644,7 +1646,8 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
} }
/* Detect a conditional jump jumping over an unconditional jump. */ /* Detect a conditional jump jumping over an unconditional jump. */
else if (this_is_condjump && ! this_is_simplejump else if ((this_is_condjump || this_is_condjump_in_parallel)
&& ! this_is_simplejump
&& reallabelprev != 0 && reallabelprev != 0
&& GET_CODE (reallabelprev) == JUMP_INSN && GET_CODE (reallabelprev) == JUMP_INSN
&& prev_active_insn (reallabelprev) == insn && prev_active_insn (reallabelprev) == insn
...@@ -2830,6 +2833,39 @@ condjump_p (insn) ...@@ -2830,6 +2833,39 @@ condjump_p (insn)
return 0; return 0;
} }
/* Return nonzero if INSN is a (possibly) conditional jump
and nothing more. */
int
condjump_in_parallel_p (insn)
rtx insn;
{
register rtx x = PATTERN (insn);
if (GET_CODE (x) != PARALLEL)
return 0;
else
x = XVECEXP (x, 0, 0);
if (GET_CODE (x) != SET)
return 0;
if (GET_CODE (SET_DEST (x)) != PC)
return 0;
if (GET_CODE (SET_SRC (x)) == LABEL_REF)
return 1;
if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE)
return 0;
if (XEXP (SET_SRC (x), 2) == pc_rtx
&& (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF
|| GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN))
return 1;
if (XEXP (SET_SRC (x), 1) == pc_rtx
&& (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF
|| GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN))
return 1;
return 0;
}
/* Return 1 if X is an RTX that does nothing but set the condition codes /* Return 1 if X is an RTX that does nothing but set the condition codes
and CLOBBER or USE registers. and CLOBBER or USE registers.
Return -1 if X does explicitly set the condition codes, Return -1 if X does explicitly set the condition codes,
......
...@@ -1194,7 +1194,7 @@ get_jump_flags (insn, label) ...@@ -1194,7 +1194,7 @@ get_jump_flags (insn, label)
If LABEL is zero, then there is no way to determine the branch If LABEL is zero, then there is no way to determine the branch
direction. */ direction. */
if (GET_CODE (insn) == JUMP_INSN if (GET_CODE (insn) == JUMP_INSN
&& condjump_p (insn) && (condjump_p (insn) || condjump_in_parallel_p (insn))
&& INSN_UID (insn) <= max_uid && INSN_UID (insn) <= max_uid
&& label != 0 && label != 0
&& INSN_UID (label) <= max_uid) && INSN_UID (label) <= max_uid)
...@@ -1210,7 +1210,7 @@ get_jump_flags (insn, label) ...@@ -1210,7 +1210,7 @@ get_jump_flags (insn, label)
Non conditional branches are predicted as very likely taken. */ Non conditional branches are predicted as very likely taken. */
if (GET_CODE (insn) == JUMP_INSN if (GET_CODE (insn) == JUMP_INSN
&& condjump_p (insn)) && (condjump_p (insn) || condjump_in_parallel_p (insn)))
{ {
int prediction; int prediction;
...@@ -1403,6 +1403,9 @@ get_branch_condition (insn, target) ...@@ -1403,6 +1403,9 @@ get_branch_condition (insn, target)
rtx pat = PATTERN (insn); rtx pat = PATTERN (insn);
rtx src; rtx src;
if (condjump_in_parallel_p (insn))
pat = XVECEXP (pat, 0, 0);
if (GET_CODE (pat) == RETURN) if (GET_CODE (pat) == RETURN)
return target == 0 ? const_true_rtx : 0; return target == 0 ? const_true_rtx : 0;
...@@ -2868,7 +2871,8 @@ fill_simple_delay_slots (first, non_jumps_p) ...@@ -2868,7 +2871,8 @@ fill_simple_delay_slots (first, non_jumps_p)
#if defined(ANNUL_IFFALSE_SLOTS) || defined(ANNUL_IFTRUE_SLOTS) #if defined(ANNUL_IFFALSE_SLOTS) || defined(ANNUL_IFTRUE_SLOTS)
if (slots_filled != slots_to_fill if (slots_filled != slots_to_fill
&& delay_list == 0 && delay_list == 0
&& GET_CODE (insn) == JUMP_INSN && condjump_p (insn)) && GET_CODE (insn) == JUMP_INSN
&& (condjump_p (insn) || condjump_in_parallel_p (insn)))
{ {
delay_list = optimize_skip (insn); delay_list = optimize_skip (insn);
if (delay_list) if (delay_list)
...@@ -2893,7 +2897,8 @@ fill_simple_delay_slots (first, non_jumps_p) ...@@ -2893,7 +2897,8 @@ fill_simple_delay_slots (first, non_jumps_p)
if (slots_filled != slots_to_fill if (slots_filled != slots_to_fill
&& (GET_CODE (insn) != JUMP_INSN && (GET_CODE (insn) != JUMP_INSN
|| (condjump_p (insn) && ! simplejump_p (insn) || ((condjump_p (insn) || condjump_in_parallel_p (insn))
&& ! simplejump_p (insn)
&& JUMP_LABEL (insn) != 0))) && JUMP_LABEL (insn) != 0)))
{ {
rtx target = 0; rtx target = 0;
...@@ -3546,7 +3551,7 @@ fill_eager_delay_slots (first) ...@@ -3546,7 +3551,7 @@ fill_eager_delay_slots (first)
if (insn == 0 if (insn == 0
|| INSN_DELETED_P (insn) || INSN_DELETED_P (insn)
|| GET_CODE (insn) != JUMP_INSN || GET_CODE (insn) != JUMP_INSN
|| ! condjump_p (insn)) || ! (condjump_p (insn) || condjump_in_parallel_p (insn)))
continue; continue;
slots_to_fill = num_delay_slots (insn); slots_to_fill = num_delay_slots (insn);
...@@ -3659,7 +3664,7 @@ relax_delay_slots (first) ...@@ -3659,7 +3664,7 @@ relax_delay_slots (first)
the next insn, or jumps to a label that is not the last of a the next insn, or jumps to a label that is not the last of a
group of consecutive labels. */ group of consecutive labels. */
if (GET_CODE (insn) == JUMP_INSN if (GET_CODE (insn) == JUMP_INSN
&& condjump_p (insn) && (condjump_p (insn) || condjump_in_parallel_p (insn))
&& (target_label = JUMP_LABEL (insn)) != 0) && (target_label = JUMP_LABEL (insn)) != 0)
{ {
target_label = follow_jumps (target_label); target_label = follow_jumps (target_label);
...@@ -3668,7 +3673,8 @@ relax_delay_slots (first) ...@@ -3668,7 +3673,8 @@ relax_delay_slots (first)
if (target_label == 0) if (target_label == 0)
target_label = find_end_label (); target_label = find_end_label ();
if (next_active_insn (target_label) == next) if (next_active_insn (target_label) == next
&& ! condjump_in_parallel_p (insn))
{ {
delete_jump (insn); delete_jump (insn);
continue; continue;
...@@ -3725,7 +3731,7 @@ relax_delay_slots (first) ...@@ -3725,7 +3731,7 @@ relax_delay_slots (first)
if (GET_CODE (insn) == JUMP_INSN if (GET_CODE (insn) == JUMP_INSN
&& (simplejump_p (insn) || GET_CODE (PATTERN (insn)) == RETURN) && (simplejump_p (insn) || GET_CODE (PATTERN (insn)) == RETURN)
&& (other = prev_active_insn (insn)) != 0 && (other = prev_active_insn (insn)) != 0
&& condjump_p (other) && (condjump_p (other) || condjump_in_parallel_p (other))
&& no_labels_between_p (other, insn) && no_labels_between_p (other, insn)
&& 0 < mostly_true_jump (other, && 0 < mostly_true_jump (other,
get_branch_condition (other, get_branch_condition (other,
...@@ -3766,7 +3772,8 @@ relax_delay_slots (first) ...@@ -3766,7 +3772,8 @@ relax_delay_slots (first)
/* Now look only at the cases where we have a filled JUMP_INSN. */ /* Now look only at the cases where we have a filled JUMP_INSN. */
if (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) != JUMP_INSN if (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) != JUMP_INSN
|| ! condjump_p (XVECEXP (PATTERN (insn), 0, 0))) || ! (condjump_p (XVECEXP (PATTERN (insn), 0, 0))
|| condjump_in_parallel_p (XVECEXP (PATTERN (insn), 0, 0))))
continue; continue;
target_label = JUMP_LABEL (delay_insn); target_label = JUMP_LABEL (delay_insn);
...@@ -3828,6 +3835,7 @@ relax_delay_slots (first) ...@@ -3828,6 +3835,7 @@ relax_delay_slots (first)
if (! INSN_ANNULLED_BRANCH_P (delay_insn) if (! INSN_ANNULLED_BRANCH_P (delay_insn)
&& prev_active_insn (target_label) == insn && prev_active_insn (target_label) == insn
&& ! condjump_in_parallel_p (delay_insn)
#ifdef HAVE_cc0 #ifdef HAVE_cc0
/* If the last insn in the delay slot sets CC0 for some insn, /* If the last insn in the delay slot sets CC0 for some insn,
various code assumes that it is in a delay slot. We could various code assumes that it is in a delay slot. We could
...@@ -4110,7 +4118,8 @@ dbr_schedule (first, file) ...@@ -4110,7 +4118,8 @@ dbr_schedule (first, file)
obstack_ptr_grow (&unfilled_slots_obstack, insn); obstack_ptr_grow (&unfilled_slots_obstack, insn);
/* Ensure all jumps go to the last of a set of consecutive labels. */ /* Ensure all jumps go to the last of a set of consecutive labels. */
if (GET_CODE (insn) == JUMP_INSN && condjump_p (insn) if (GET_CODE (insn) == JUMP_INSN
&& (condjump_p (insn) || condjump_in_parallel_p (insn))
&& JUMP_LABEL (insn) != 0 && JUMP_LABEL (insn) != 0
&& ((target = prev_label (next_active_insn (JUMP_LABEL (insn)))) && ((target = prev_label (next_active_insn (JUMP_LABEL (insn))))
!= JUMP_LABEL (insn))) != JUMP_LABEL (insn)))
......
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