This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: (i386-linux x sh-elf) build breakage
- To: rth at cygnus dot com (Richard Henderson)
- Subject: Re: (i386-linux x sh-elf) build breakage
- From: Joern Rennecke <amylaar at redhat dot com>
- Date: Wed, 13 Dec 2000 19:15:43 +0000 (GMT)
- Cc: tm at netcom dot com (Toshiyasu Morita), gcc at gcc dot gnu dot org
> On Wed, Jul 19, 2000 at 06:44:53PM +0100, Joern Rennecke wrote:
> > cse and the loop optimizer wouldn't understand these branches. I think it
> > would be better to allow splits that generate new basic blocks.
>
> The first post-reload splitter can generate new blocks.
I thought so far that jump would redirect jumps where appropriate; however,
I've seen now that it won't redirect (cond)jumps to condjumps after reload.
thread_jumps is only called twice, both times before combine; and
follow_jumps doesn't follow condjumps.
Now, it would be possible to call thread_jumps again after the post-reload
splitter, however, this might be overkill and slow down compilation too much.
The following patch instead changes follow_jumps so that it also follows
conditional jump when the condition is known from the first branch.
Wed Dec 13 19:13:19 2000 J"orn Rennecke <amylaar@redhat.com>
* rtl.h (follow_jumps): Add second argument to declaration.
* jump.c (follow_jumps): Add second argument. Changed all callers.
Index: rtl.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/rtl.h,v
retrieving revision 1.172
diff -p -r1.172 rtl.h
*** rtl.h 2000/11/22 01:36:43 1.172
--- rtl.h 2000/12/13 19:12:44
*************** extern void delete_jump PARAMS ((rtx))
*** 1296,1302 ****
extern void delete_barrier PARAMS ((rtx));
extern rtx get_label_before PARAMS ((rtx));
extern rtx get_label_after PARAMS ((rtx));
! extern rtx follow_jumps PARAMS ((rtx));
/* In recog.c */
extern rtx adj_offsettable_operand PARAMS ((rtx, int));
--- 1296,1302 ----
extern void delete_barrier PARAMS ((rtx));
extern rtx get_label_before PARAMS ((rtx));
extern rtx get_label_after PARAMS ((rtx));
! extern rtx follow_jumps PARAMS ((rtx, rtx));
/* In recog.c */
extern rtx adj_offsettable_operand PARAMS ((rtx, int));
Index: jump.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/jump.c,v
retrieving revision 1.186
diff -p -r1.186 jump.c
*** jump.c 2000/12/02 00:31:14 1.186
--- jump.c 2000/12/13 19:12:45
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 348,354 ****
changed |= tension_vector_labels (PATTERN (insn), 1);
/* See if this jump goes to another jump and redirect if so. */
! nlabel = follow_jumps (JUMP_LABEL (insn));
if (nlabel != JUMP_LABEL (insn))
changed |= redirect_jump (insn, nlabel, 1);
--- 348,356 ----
changed |= tension_vector_labels (PATTERN (insn), 1);
/* See if this jump goes to another jump and redirect if so. */
! nlabel = follow_jumps (JUMP_LABEL (insn),
! (this_is_any_condjump
! ? pc_set (insn) : NULL_RTX));
if (nlabel != JUMP_LABEL (insn))
changed |= redirect_jump (insn, nlabel, 1);
*************** sets_cc0_p (x)
*** 2310,2315 ****
--- 2312,2320 ----
/* Follow any unconditional jump at LABEL;
return the ultimate label reached by any such chain of jumps.
+ If PC_SET_RTX is non-zero, it is the SET that sets pc to reach
+ LABEL. If a following jump shares the same condition that is used in
+ PC_SET_RTX, we consider it unconditional here.
If LABEL is not followed by a jump, return LABEL.
If the chain loops or we can't find end, return LABEL,
since that tells caller to avoid changing the insn.
*************** sets_cc0_p (x)
*** 2318,2340 ****
a USE or CLOBBER. */
rtx
! follow_jumps (label)
rtx label;
{
register rtx insn;
register rtx next;
register rtx value = label;
register int depth;
for (depth = 0;
(depth < 10
&& (insn = next_active_insn (value)) != 0
! && GET_CODE (insn) == JUMP_INSN
! && ((JUMP_LABEL (insn) != 0 && any_uncondjump_p (insn)
! && onlyjump_p (insn))
! || GET_CODE (PATTERN (insn)) == RETURN)
! && (next = NEXT_INSN (insn))
! && GET_CODE (next) == BARRIER);
depth++)
{
/* Don't chain through the insn that jumps into a loop
--- 2323,2368 ----
a USE or CLOBBER. */
rtx
! follow_jumps (label, pc_set_rtx)
rtx label;
+ rtx pc_set_rtx;
{
+ rtx pc_src;
register rtx insn;
register rtx next;
register rtx value = label;
register int depth;
+ enum rtx_code test_code = UNKNOWN, test_code_rev = UNKNOWN;
+ rtx test_exp0, test_exp1;
+ if (pc_set_rtx)
+ pc_src = SET_SRC (pc_set_rtx);
+ if (pc_set_rtx && GET_CODE (pc_src) == IF_THEN_ELSE)
+ {
+ test_code = NE;
+ test_exp0 = XEXP (pc_src, 0);
+ test_exp1 = const0_rtx;
+ if (GET_RTX_CLASS (GET_CODE (test_exp0)) == '<')
+ {
+ test_code = GET_CODE (test_exp0);
+ test_exp1 = XEXP (test_exp0, 1);
+ test_exp0 = XEXP (test_exp0, 0);
+ }
+ if (GET_CODE (XEXP (pc_src, 2)) == LABEL_REF)
+ {
+ if (can_reverse_comparison_p (XEXP (pc_src, 0), NULL_RTX))
+ test_code = reverse_condition (test_code);
+ else
+ test_code = UNKNOWN;
+ }
+ if (test_code != UNKNOWN
+ && can_reverse_comparison_p (XEXP (pc_src, 0), NULL_RTX))
+ test_code_rev = reverse_condition (test_code);
+ }
for (depth = 0;
(depth < 10
&& (insn = next_active_insn (value)) != 0
! && GET_CODE (insn) == JUMP_INSN);
depth++)
{
/* Don't chain through the insn that jumps into a loop
*************** follow_jumps (label)
*** 2351,2366 ****
|| (flag_test_coverage && NOTE_LINE_NUMBER (tem) > 0)))
return value;
- /* If we have found a cycle, make the insn jump to itself. */
- if (JUMP_LABEL (insn) == label)
- return label;
-
tem = next_active_insn (JUMP_LABEL (insn));
if (tem && (GET_CODE (PATTERN (tem)) == ADDR_VEC
|| GET_CODE (PATTERN (tem)) == ADDR_DIFF_VEC))
break;
! value = JUMP_LABEL (insn);
}
if (depth == 10)
return label;
--- 2379,2428 ----
|| (flag_test_coverage && NOTE_LINE_NUMBER (tem) > 0)))
return value;
tem = next_active_insn (JUMP_LABEL (insn));
if (tem && (GET_CODE (PATTERN (tem)) == ADDR_VEC
|| GET_CODE (PATTERN (tem)) == ADDR_DIFF_VEC))
break;
! if (((JUMP_LABEL (insn) != 0 && any_uncondjump_p (insn)
! && onlyjump_p (insn))
! || GET_CODE (PATTERN (insn)) == RETURN)
! && (next = NEXT_INSN (insn))
! && GET_CODE (next) == BARRIER)
! value = JUMP_LABEL (insn);
! else if (test_code != UNKNOWN
! && any_condjump_p (insn)
! && GET_CODE (pc_src = SET_SRC (pc_set (insn))) == IF_THEN_ELSE
! && onlyjump_p (insn))
! {
! enum rtx_code test2_code = NE;
! rtx test2_exp0 = XEXP (pc_src, 0);
! rtx test2_exp1 = const0_rtx;
!
! if (GET_RTX_CLASS (GET_CODE (test2_exp0)) == '<')
! {
! test2_code = GET_CODE (test2_exp0);
! test2_exp1 = XEXP (test2_exp0, 1);
! test2_exp0 = XEXP (test2_exp0, 0);
! }
! /* Check if this condjump will be taken - to a known destination -
! if the first jump was taken. */
! if (JUMP_LABEL (insn) != 0
! && test2_code == (GET_CODE (XEXP (pc_src, 2)) == LABEL_REF
! ? test_code_rev : test_code)
! && rtx_equal_p (test2_exp0, test_exp0)
! && rtx_equal_p (test2_exp1, test_exp1))
! value = JUMP_LABEL (insn);
! /* Check if this condjump will not be taken if the first jump
! was taken. */
! else if (test2_code == (GET_CODE (XEXP (pc_src, 2)) == LABEL_REF
! ? test_code : test_code_rev)
! && rtx_equal_p (test2_exp0, test_exp0)
! && rtx_equal_p (test2_exp1, test_exp1))
! value = get_label_after (insn);
! }
! else
! break;
}
if (depth == 10)
return label;
*************** tension_vector_labels (x, idx)
*** 2382,2388 ****
for (i = XVECLEN (x, idx) - 1; i >= 0; i--)
{
register rtx olabel = XEXP (XVECEXP (x, idx, i), 0);
! register rtx nlabel = follow_jumps (olabel);
if (nlabel && nlabel != olabel)
{
XEXP (XVECEXP (x, idx, i), 0) = nlabel;
--- 2444,2450 ----
for (i = XVECLEN (x, idx) - 1; i >= 0; i--)
{
register rtx olabel = XEXP (XVECEXP (x, idx, i), 0);
! register rtx nlabel = follow_jumps (olabel, NULL_RTX);
if (nlabel && nlabel != olabel)
{
XEXP (XVECEXP (x, idx, i), 0) = nlabel;
Index: reorg.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/reorg.c,v
retrieving revision 1.126
diff -p -r1.126 reorg.c
*** reorg.c 2000/11/13 22:30:41 1.126
--- reorg.c 2000/12/13 19:12:48
*************** fill_slots_from_thread (insn, condition,
*** 2891,2897 ****
&& redirect_with_delay_list_safe_p (insn,
JUMP_LABEL (new_thread),
delay_list))
! new_thread = follow_jumps (JUMP_LABEL (new_thread));
if (new_thread == 0)
label = find_end_label ();
--- 2891,2898 ----
&& redirect_with_delay_list_safe_p (insn,
JUMP_LABEL (new_thread),
delay_list))
! new_thread = follow_jumps (JUMP_LABEL (new_thread),
! pc_set (new_thread));
if (new_thread == 0)
label = find_end_label ();
*************** relax_delay_slots (first)
*** 3065,3071 ****
&& (condjump_p (insn) || condjump_in_parallel_p (insn))
&& (target_label = JUMP_LABEL (insn)) != 0)
{
! target_label = follow_jumps (target_label);
target_label = prev_label (next_active_insn (target_label));
if (target_label == 0)
--- 3066,3072 ----
&& (condjump_p (insn) || condjump_in_parallel_p (insn))
&& (target_label = JUMP_LABEL (insn)) != 0)
{
! target_label = follow_jumps (target_label, pc_set (target_label));
target_label = prev_label (next_active_insn (target_label));
if (target_label == 0)
*************** relax_delay_slots (first)
*** 3206,3212 ****
{
/* If this jump goes to another unconditional jump, thread it, but
don't convert a jump into a RETURN here. */
! trial = follow_jumps (target_label);
/* We use next_real_insn instead of next_active_insn, so that
the special USE insns emitted by reorg won't be ignored.
If they are ignored, then they will get deleted if target_label
--- 3207,3213 ----
{
/* If this jump goes to another unconditional jump, thread it, but
don't convert a jump into a RETURN here. */
! trial = follow_jumps (target_label, pc_set (target_label));
/* We use next_real_insn instead of next_active_insn, so that
the special USE insns emitted by reorg won't be ignored.
If they are ignored, then they will get deleted if target_label