This is the mail archive of the gcc-patches@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]

Fix to ARM problem without pessimizing RS/6000


Mark and RTH and I have been working on this patch, which I committed to
both the mainline and branch.  I tested on the mainline on Alpha and
on the branch with x86.

Wed Mar 21 14:27:11 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* cse.c (find_comparison_args): Remove previous change.
	* ifcvt.c (noce_process_if_block): When moving an insn, remove any
	REG_EQUAL notes.

*** cse.c	2001/03/19 18:53:03	1.179
--- cse.c	2001/03/21 19:07:43
*************** find_best_addr (insn, loc, mode)
*** 3087,3109 ****
  }
  
! /* This routine accepts a comparison as input and attempts to return a
!    comparision that is cheaper to compute.
  
!    On input, *PARG1 and *PARG2 should be set to the first and second
!    arguments to the comparison, respectively.  CODE is the comparision
!    code.  For example, if the comparison is:
! 
!      (ne:SI (reg:CC 24 cc)
!             (const_int 0 [0x0])))
! 
!    The CODE should be NE, *PARG1 should be `(reg:CC 24 cc)' and 
!    *PARG2 should be `(const_int 0)'.
! 
!    Upon return, *PARG1 and and *PARG2 may have new values, indicating
!    arguments to a cheaper comparison.  *PMODE1 and *PMODE2 will be the
!    modes that should be used for those arguments.  The return value
!    itself will be the comparison code that should be used to compare
!    *PARG1 and *PARG2 in order to obtain a value equivalent to that
!    given by the original comparison.  */
  
  static enum rtx_code
--- 3087,3101 ----
  }
  
! /* Given an operation (CODE, *PARG1, *PARG2), where code is a comparison
!    operation (EQ, NE, GT, etc.), follow it back through the hash table and
!    what values are being compared.
! 
!    *PARG1 and *PARG2 are updated to contain the rtx representing the values
!    actually being compared.  For example, if *PARG1 was (cc0) and *PARG2
!    was (const_int 0), *PARG1 and *PARG2 will be set to the objects that were
!    compared to produce cc0.
  
!    The return value is the comparison operator and is either the code of
!    A or the code corresponding to the inverse of the comparison.  */
  
  static enum rtx_code
*************** find_comparison_args (code, parg1, parg2
*** 3196,3231 ****
  	    continue;
  
! 	  /* `(COMPARE A B) != 0)' is equivalent to `(COMPARE A B)'.
! 	     If CODE is EQ, rather than NE, then we are out of luck;
! 	     there is no way to reverse the sense of a COMPARE.  */
! 	  if (code == NE && GET_CODE (p->exp) == COMPARE)
! 	    {
! 	      x = p->exp;
! 	      break;
! 	    }
! 	  /* Another possibility is that this machine has a compare
! 	     insn that includes the comparison code.  In that case,
! 	     ARG1 would be equivalent to a comparison operation that
! 	     would set ARG1 to either STORE_FLAG_VALUE or zero.  If
! 	     this is an NE operation, ORIG_CODE is the actual
! 	     comparison being done; if it is an EQ, we must reverse
! 	     ORIG_CODE.  On machine with a negative value for
! 	     STORE_FLAG_VALUE, also look at LT and GE operations.  */
! 	  else if ((code == NE
! 		    || (code == LT
! 			&& GET_MODE_CLASS (inner_mode) == MODE_INT
! 			&& (GET_MODE_BITSIZE (inner_mode)
! 			    <= HOST_BITS_PER_WIDE_INT)
! 			&& (STORE_FLAG_VALUE
! 			    & ((HOST_WIDE_INT) 1
! 			       << (GET_MODE_BITSIZE (inner_mode) - 1))))
  #ifdef FLOAT_STORE_FLAG_VALUE
! 		    || (code == LT
! 			&& GET_MODE_CLASS (inner_mode) == MODE_FLOAT
! 			&& (REAL_VALUE_NEGATIVE
! 			    (FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)))))
  #endif
! 		    )
! 		   && GET_RTX_CLASS (GET_CODE (p->exp)) == '<')
  	    {
  	      x = p->exp;
--- 3188,3215 ----
  	    continue;
  
! 	  if (GET_CODE (p->exp) == COMPARE
! 	      /* Another possibility is that this machine has a compare insn
! 		 that includes the comparison code.  In that case, ARG1 would
! 		 be equivalent to a comparison operation that would set ARG1 to
! 		 either STORE_FLAG_VALUE or zero.  If this is an NE operation,
! 		 ORIG_CODE is the actual comparison being done; if it is an EQ,
! 		 we must reverse ORIG_CODE.  On machine with a negative value
! 		 for STORE_FLAG_VALUE, also look at LT and GE operations.  */
! 	      || ((code == NE
! 		   || (code == LT
! 		       && GET_MODE_CLASS (inner_mode) == MODE_INT
! 		       && (GET_MODE_BITSIZE (inner_mode)
! 			   <= HOST_BITS_PER_WIDE_INT)
! 		       && (STORE_FLAG_VALUE
! 			   & ((HOST_WIDE_INT) 1
! 			      << (GET_MODE_BITSIZE (inner_mode) - 1))))
  #ifdef FLOAT_STORE_FLAG_VALUE
! 		   || (code == LT
! 		       && GET_MODE_CLASS (inner_mode) == MODE_FLOAT
! 		       && (REAL_VALUE_NEGATIVE
! 			   (FLOAT_STORE_FLAG_VALUE (GET_MODE (arg1)))))
  #endif
! 		   )
! 		  && GET_RTX_CLASS (GET_CODE (p->exp)) == '<'))
  	    {
  	      x = p->exp;
*** ifcvt.c	2001/03/07 19:29:36	1.42
--- ifcvt.c	2001/03/21 19:08:05
*************** noce_process_if_block (test_bb, then_bb,
*** 1564,1570 ****
--- 1564,1578 ----
        if (insn_b && else_bb)
  	{
+ 	  rtx note;
+ 
  	  if (else_bb && insn_b == else_bb->end)
  	    else_bb->end = PREV_INSN (insn_b);
  	  reorder_insns (insn_b, insn_b, PREV_INSN (if_info.cond_earliest));
+ 
+ 	  /* If there was a REG_EQUAL note, delete it since it may have been
+ 	     true due to this insn being after a jump.  */
+ 	  if ((note = find_reg_note (insn_b, REG_EQUAL, NULL_RTX)) != 0)
+ 	    remove_note (insn_b, note);
+ 
  	  insn_b = NULL_RTX;
  	}
  


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