This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: (i386-linux x sh-elf) build breakage


> 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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]