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]

Patch to make get_condition more flexible.


This patch allows get_condition to be used to canonize conditions
for conditional moves and store conditions.  This is used by value
range propagation.

ChangeLog:

Sun Feb 13 11:55:34 EST 2000  John Wehle  (john@feith.com)

	* loop.c (get_condition): New argument COND.
	(check_dbra_loop, get_condition_for_loop): Update
	for new argument to get_condition.
	* gcse.c (delete_null_pointers_check_1,
	delete_null_pointers_check): Likewise.
	* jump.c (jump_optimize_1): Likewise.
	* predict.c (estimate_probability): Likewise.
	* expr.h (get_condition): Update prototype.

Enjoy!

-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/loop.c.ORIGINAL	Sat Feb  5 14:16:32 2000
--- gcc/loop.c	Sun Feb 13 11:50:42 2000
*************** check_dbra_loop (loop, insn_count)
*** 7880,7886 ****
  
    /* Try to compute whether the compare/branch at the loop end is one or
       two instructions.  */
!   get_condition (jump, &first_compare);
    if (first_compare == jump)
      compare_and_branch = 1;
    else if (first_compare == prev_nonnote_insn (jump))
--- 7880,7886 ----
  
    /* Try to compute whether the compare/branch at the loop end is one or
       two instructions.  */
!   get_condition (jump, NULL_RTX, &first_compare);
    if (first_compare == jump)
      compare_and_branch = 1;
    else if (first_compare == prev_nonnote_insn (jump))
*************** update_reg_last_use (x, insn)
*** 8995,9026 ****
      }
  }
  
! /* Given a jump insn JUMP, return the condition that will cause it to branch
!    to its JUMP_LABEL.  If the condition cannot be understood, or is an
!    inequality floating-point comparison which needs to be reversed, 0 will
!    be returned.
! 
!    If EARLIEST is non-zero, it is a pointer to a place where the earliest
!    insn used in locating the condition was found.  If a replacement test
!    of the condition is desired, it should be placed in front of that
!    insn and we will be sure that the inputs are still valid.
! 
!    The condition will be returned in a canonical form to simplify testing by
!    callers.  Specifically:
  
     (1) The code will always be a comparison operation (EQ, NE, GT, etc.).
     (2) Both operands will be machine operands; (cc0) will have been replaced.
     (3) If an operand is a constant, it will be the second operand.
     (4) (LE x const) will be replaced with (LT x <const+1>) and similarly
!        for GE, GEU, and LEU.  */
  
  rtx
! get_condition (jump, earliest)
!      rtx jump;
       rtx *earliest;
  {
    enum rtx_code code;
!   rtx prev = jump;
    rtx set;
    rtx tem;
    rtx op0, op1;
--- 8995,9027 ----
      }
  }
  
! /* Given an insn INSN and condition COND, return the condition in a
!    canonical form to simplify testing by callers.  Specifically:
  
     (1) The code will always be a comparison operation (EQ, NE, GT, etc.).
     (2) Both operands will be machine operands; (cc0) will have been replaced.
     (3) If an operand is a constant, it will be the second operand.
     (4) (LE x const) will be replaced with (LT x <const+1>) and similarly
!        for GE, GEU, and LEU.
! 
!    COND can be NULL_RTX if INSN is a jump insn in which case the condition
!    that will cause INSN to branch to its JUMP_LABEL will be returned.
!    If the condition cannot be understood, or is an inequality floating-point
!    comparison which needs to be reversed, 0 will be returned.
! 
!    If EARLIEST is non-zero, it is a pointer to a place where the earliest
!    insn used in locating the condition was found.  If a replacement test
!    of the condition is desired, it should be placed in front of that
!    insn and we will be sure that the inputs are still valid.  */
  
  rtx
! get_condition (insn, cond, earliest)
!      rtx insn;
!      rtx cond;
       rtx *earliest;
  {
    enum rtx_code code;
!   rtx prev = insn;
    rtx set;
    rtx tem;
    rtx op0, op1;
*************** get_condition (jump, earliest)
*** 9028,9051 ****
    int did_reverse_condition = 0;
    enum machine_mode mode;
  
!   /* If this is not a standard conditional jump, we can't parse it.  */
!   if (GET_CODE (jump) != JUMP_INSN
!       || ! condjump_p (jump) || simplejump_p (jump))
!     return 0;
  
!   code = GET_CODE (XEXP (SET_SRC (PATTERN (jump)), 0));
!   mode = GET_MODE (XEXP (SET_SRC (PATTERN (jump)), 0));
!   op0 = XEXP (XEXP (SET_SRC (PATTERN (jump)), 0), 0);
!   op1 = XEXP (XEXP (SET_SRC (PATTERN (jump)), 0), 1);
  
    if (earliest)
!     *earliest = jump;
! 
!   /* If this branches to JUMP_LABEL when the condition is false, reverse
!      the condition.  */
!   if (GET_CODE (XEXP (SET_SRC (PATTERN (jump)), 2)) == LABEL_REF
!       && XEXP (XEXP (SET_SRC (PATTERN (jump)), 2), 0) == JUMP_LABEL (jump))
!     code = reverse_condition (code), did_reverse_condition ^= 1;
  
    /* If we are comparing a register with zero, see if the register is set
       in the previous insn to a COMPARE or a comparison operation.  Perform
--- 9029,9057 ----
    int did_reverse_condition = 0;
    enum machine_mode mode;
  
!   if (cond == NULL_RTX)
!     {
!       /* If this is not a standard conditional jump, we can't parse it.  */
!       if (GET_CODE (insn) != JUMP_INSN
! 	  || ! condjump_p (insn) || simplejump_p (insn))
! 	return 0;
!       cond = XEXP (SET_SRC (PATTERN (insn)), 0);
!       code = GET_CODE (cond);
!       /* If this branches to JUMP_LABEL when the condition is false, reverse
! 	 the condition.  */
!       if (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 2)) == LABEL_REF
! 	  && XEXP (XEXP (SET_SRC (PATTERN (insn)), 2), 0) == JUMP_LABEL (insn))
! 	code = reverse_condition (code), did_reverse_condition ^= 1;
!     }
!   else
!     code = GET_CODE (cond);
  
!   mode = GET_MODE (cond);
!   op0 = XEXP (cond, 0);
!   op1 = XEXP (cond, 1);
  
    if (earliest)
!     *earliest = insn;
  
    /* If we are comparing a register with zero, see if the register is set
       in the previous insn to a COMPARE or a comparison operation.  Perform
*************** get_condition_for_loop (loop, x)
*** 9270,9276 ****
       const struct loop *loop;
       rtx x;
  {
!   rtx comparison = get_condition (x, NULL_PTR);
  
    if (comparison == 0
        || ! loop_invariant_p (loop, XEXP (comparison, 0))
--- 9276,9282 ----
       const struct loop *loop;
       rtx x;
  {
!   rtx comparison = get_condition (x, NULL_RTX, NULL_PTR);
  
    if (comparison == 0
        || ! loop_invariant_p (loop, XEXP (comparison, 0))
*** gcc/gcse.c.ORIGINAL	Sun Feb 13 11:04:50 2000
--- gcc/gcse.c	Sun Feb 13 11:24:32 2000
*************** delete_null_pointer_checks_1 (block_reg,
*** 8303,8309 ****
  	continue;
  
        /* LAST_INSN is a conditional jump.  Get its condition.  */
!       condition = get_condition (last_insn, &earliest);
  
        /* If we can't determine the condition then skip.  */
        if (! condition)
--- 8303,8309 ----
  	continue;
  
        /* LAST_INSN is a conditional jump.  Get its condition.  */
!       condition = get_condition (last_insn, NULL_RTX, &earliest);
  
        /* If we can't determine the condition then skip.  */
        if (! condition)
*************** delete_null_pointer_checks (f)
*** 8435,8441 ****
  	continue;
  
        /* LAST_INSN is a conditional jump.  Get its condition.  */
!       condition = get_condition (last_insn, &earliest);
  
        /* If we were unable to get the condition, or it is not a equality
  	 comparison against zero then there's nothing we can do.  */
--- 8435,8441 ----
  	continue;
  
        /* LAST_INSN is a conditional jump.  Get its condition.  */
!       condition = get_condition (last_insn, NULL_RTX, &earliest);
  
        /* If we were unable to get the condition, or it is not a equality
  	 comparison against zero then there's nothing we can do.  */
*** gcc/jump.c.ORIGINAL	Sat Feb  5 14:16:31 2000
--- gcc/jump.c	Sun Feb 13 11:23:08 2000
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 1141,1147 ****
  		  || ((temp3 = next_active_insn (temp)) != 0
  		      && simplejump_p (temp3)
  		      && JUMP_LABEL (temp3) == JUMP_LABEL (insn)))
! 	      && (temp3 = get_condition (insn, &temp4)) != 0
  	      /* We must be comparing objects whose modes imply the size.
  		 We could handle BLKmode if (1) emit_store_flag could
  		 and (2) we could find the size reliably.  */
--- 1141,1147 ----
  		  || ((temp3 = next_active_insn (temp)) != 0
  		      && simplejump_p (temp3)
  		      && JUMP_LABEL (temp3) == JUMP_LABEL (insn)))
! 	      && (temp3 = get_condition (insn, NULL_RTX, &temp4)) != 0
  	      /* We must be comparing objects whose modes imply the size.
  		 We could handle BLKmode if (1) emit_store_flag could
  		 and (2) we could find the size reliably.  */
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 1289,1295 ****
  		  || ((temp4 = next_active_insn (temp)) != 0
  		      && simplejump_p (temp4)
  		      && JUMP_LABEL (temp4) == JUMP_LABEL (insn)))
! 	      && (temp4 = get_condition (insn, &temp5)) != 0
  	      /* We must be comparing objects whose modes imply the size.
  		 We could handle BLKmode if (1) emit_store_flag could
  		 and (2) we could find the size reliably.  */
--- 1289,1295 ----
  		  || ((temp4 = next_active_insn (temp)) != 0
  		      && simplejump_p (temp4)
  		      && JUMP_LABEL (temp4) == JUMP_LABEL (insn)))
! 	      && (temp4 = get_condition (insn, NULL_RTX, &temp5)) != 0
  	      /* We must be comparing objects whose modes imply the size.
  		 We could handle BLKmode if (1) emit_store_flag could
  		 and (2) we could find the size reliably.  */
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 1930,1936 ****
  		   && TRAP_CONDITION (PATTERN (reallabelprev)) == const_true_rtx
  		   && prev_active_insn (reallabelprev) == insn
  		   && no_labels_between_p (insn, reallabelprev)
! 		   && (temp2 = get_condition (insn, &temp4))
  		   && can_reverse_comparison_p (temp2, insn))
  	    {
  	      rtx new = gen_cond_trap (reverse_condition (GET_CODE (temp2)),
--- 1930,1936 ----
  		   && TRAP_CONDITION (PATTERN (reallabelprev)) == const_true_rtx
  		   && prev_active_insn (reallabelprev) == insn
  		   && no_labels_between_p (insn, reallabelprev)
! 		   && (temp2 = get_condition (insn, NULL_RTX, &temp4))
  		   && can_reverse_comparison_p (temp2, insn))
  	    {
  	      rtx new = gen_cond_trap (reverse_condition (GET_CODE (temp2)),
*************** jump_optimize_1 (f, cross_jump, noop_mov
*** 1952,1958 ****
  		   && GET_CODE (temp) == INSN
  		   && GET_CODE (PATTERN (temp)) == TRAP_IF
  		   && (this_is_simplejump
! 		       || (temp2 = get_condition (insn, &temp4))))
  	    {
  	      rtx tc = TRAP_CONDITION (PATTERN (temp));
  
--- 1952,1958 ----
  		   && GET_CODE (temp) == INSN
  		   && GET_CODE (PATTERN (temp)) == TRAP_IF
  		   && (this_is_simplejump
! 		       || (temp2 = get_condition (insn, NULL_RTX, &temp4))))
  	    {
  	      rtx tc = TRAP_CONDITION (PATTERN (temp));
  
*** gcc/predict.c.ORIGINAL	Sat Feb  5 14:16:34 2000
--- gcc/predict.c	Sun Feb 13 11:23:37 2000
*************** estimate_probability (loops_info)
*** 83,89 ****
  		  if (GET_CODE (last_insn) != JUMP_INSN
  		      || ! condjump_p (last_insn) || simplejump_p (last_insn))
  		    continue;
! 		  cond = get_condition (last_insn, &earliest);
  		  if (! cond)
  		    continue;
  		  if (! find_reg_note (last_insn, REG_BR_PROB, 0))
--- 83,89 ----
  		  if (GET_CODE (last_insn) != JUMP_INSN
  		      || ! condjump_p (last_insn) || simplejump_p (last_insn))
  		    continue;
! 		  cond = get_condition (last_insn, NULL_RTX, &earliest);
  		  if (! cond)
  		    continue;
  		  if (! find_reg_note (last_insn, REG_BR_PROB, 0))
*************** estimate_probability (loops_info)
*** 105,111 ****
        if (GET_CODE (last_insn) != JUMP_INSN
  	  || ! condjump_p (last_insn) || simplejump_p (last_insn))
  	continue;
!       cond = get_condition (last_insn, &earliest);
        if (! cond)
  	continue;
        /* EQ tests are usually false and NE tests are usually true.  Also,
--- 105,111 ----
        if (GET_CODE (last_insn) != JUMP_INSN
  	  || ! condjump_p (last_insn) || simplejump_p (last_insn))
  	continue;
!       cond = get_condition (last_insn, NULL_RTX, &earliest);
        if (! cond)
  	continue;
        /* EQ tests are usually false and NE tests are usually true.  Also,
*** gcc/expr.h.ORIGINAL	Sat Feb  5 14:16:11 2000
--- gcc/expr.h	Sun Feb 13 11:22:01 2000
*************** extern rtx emit_store_flag_force PARAMS 
*** 888,895 ****
  
  /* Functions from loop.c:  */
  
! /* Given a JUMP_INSN, return a description of the test being made.  */
! extern rtx get_condition PARAMS ((rtx, rtx *));
  
  /* Generate a conditional trap instruction.  */
  extern rtx gen_cond_trap PARAMS ((enum rtx_code, rtx, rtx, rtx));
--- 888,897 ----
  
  /* Functions from loop.c:  */
  
! /* Given an INSN and condition, return a canonical description of the
!    test being made.  NULL_RTX may be used as the condition in the case
!    of a JUMP_INSN.  */
! extern rtx get_condition PARAMS ((rtx, rtx, rtx *));
  
  /* Generate a conditional trap instruction.  */
  extern rtx gen_cond_trap PARAMS ((enum rtx_code, rtx, rtx, rtx));
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: john@feith.com  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------


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