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]
Other format: [Raw text]

Re: [Bug 10914] New: unswitch loops does not work on powerpc


Hello,

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10914
> 
>            Summary: unswitch loops does not work on powerpc
>            Product: gcc
>            Version: 3.4
>             Status: UNCONFIRMED
>           Severity: normal
>           Priority: P2
>          Component: optimization
>         AssignedTo: unassigned@gcc.gnu.org
>         ReportedBy: pinskia@physics.uc.edu
>                 CC: gcc-bugs@gcc.gnu.org,pinskia@physics.uc.edu
>  GCC build triplet: powerpc-apple-darwin6.6
>   GCC host triplet: powerpc-apple-darwin6.6
> GCC target triplet: powerpc-apple-darwin6.6
> 
> unswitch loops does not work on powerpc because powerpc has multiple
> conditional registers.

... and the invariant comparison is moved out of the loop.  This patch
persuades get_condition to return the comparison of the appropriate
cc mode register in this case, thus enabling us to proceed normally.

Not regtested/bootstrapped yet (I am just leaving for the gcc summit);
ok if it passes?

Zdenek

	* expr.h (get_condition, canonicalize_condition): Declaration changed.
	* cfgloopanal.c (simple_loop_exit_p): Add parameter to a get_condition
	and canonicalize_condition calls.
	* gcse.c (fis_get_condition, delete_null_pointer_checks_1,
	delete_null_pointer_checks): Ditto.
	* ifcvt.c (noce_get_alt_condition, noce_get_condition): Ditto.
	* predict.c (estimate_probability, expected_value_to_br_prob): Ditto.
	* loop.c (check_dbra_loop, get_condition_for_loop): Ditto.
	(canonicalize_condition, get_condition): Allow to return comparisons
	of cc mode registers.
	* loop-unswitch.c (may_unswitch_on_p, unswitch_single_loop): Allow
	cc mode registers comparison in condition.

Index: cfgloopanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloopanal.c,v
retrieving revision 1.6
diff -c -3 -p -r1.6 cfgloopanal.c
*** cfgloopanal.c	17 May 2003 01:40:35 -0000	1.6
--- cfgloopanal.c	24 May 2003 06:35:29 -0000
*************** simple_loop_exit_p (loops, loop, exit_ed
*** 698,704 ****
  
    /* Condition must be a simple comparison in that one of operands
       is register and the other one is invariant.  */
!   if (!(condition = get_condition (exit_bb->end, NULL)))
      return false;
  
    if (!simple_condition_p (loop, condition, invariant_regs, desc))
--- 698,704 ----
  
    /* Condition must be a simple comparison in that one of operands
       is register and the other one is invariant.  */
!   if (!(condition = get_condition (exit_bb->end, NULL, false)))
      return false;
  
    if (!simple_condition_p (loop, condition, invariant_regs, desc))
Index: expr.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.h,v
retrieving revision 1.137
diff -c -3 -p -r1.137 expr.h
*** expr.h	12 May 2003 09:51:11 -0000	1.137
--- expr.h	24 May 2003 06:35:29 -0000
*************** extern rtx emit_store_flag_force PARAMS 
*** 331,341 ****
  
  /* Given an insn and condition, return a canonical description of
     the test being made.  */
! extern rtx canonicalize_condition PARAMS ((rtx, rtx, int, rtx *, rtx));
  
  /* Given a JUMP_INSN, return a canonical 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));
--- 331,341 ----
  
  /* Given an insn and condition, return a canonical description of
     the test being made.  */
! extern rtx canonicalize_condition PARAMS ((rtx, rtx, int, rtx *, rtx, int));
  
  /* Given a JUMP_INSN, return a canonical description of the test
     being made.  */
! extern rtx get_condition PARAMS ((rtx, rtx *, int));
  
  /* Generate a conditional trap instruction.  */
  extern rtx gen_cond_trap PARAMS ((enum rtx_code, rtx, rtx, rtx));
Index: gcse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
retrieving revision 1.249
diff -c -3 -p -r1.249 gcse.c
*** gcse.c	21 May 2003 01:16:32 -0000	1.249
--- gcse.c	24 May 2003 06:35:29 -0000
*************** fis_get_condition (jump)
*** 4630,4636 ****
  
    /* Use canonicalize_condition to do the dirty work of manipulating
       MODE_CC values and COMPARE rtx codes.  */
!   tmp = canonicalize_condition (jump, cond, reverse, &earliest, NULL_RTX);
    if (!tmp)
      return NULL_RTX;
  
--- 4630,4637 ----
  
    /* Use canonicalize_condition to do the dirty work of manipulating
       MODE_CC values and COMPARE rtx codes.  */
!   tmp = canonicalize_condition (jump, cond, reverse, &earliest, NULL_RTX,
! 				false);
    if (!tmp)
      return NULL_RTX;
  
*************** fis_get_condition (jump)
*** 4648,4654 ****
    tmp = XEXP (tmp, 0);
    if (!REG_P (tmp) || GET_MODE_CLASS (GET_MODE (tmp)) != MODE_INT)
      return NULL_RTX;
!   tmp = canonicalize_condition (jump, cond, reverse, &earliest, tmp);
    if (!tmp)
      return NULL_RTX;
  
--- 4649,4656 ----
    tmp = XEXP (tmp, 0);
    if (!REG_P (tmp) || GET_MODE_CLASS (GET_MODE (tmp)) != MODE_INT)
      return NULL_RTX;
!   tmp = canonicalize_condition (jump, cond, reverse, &earliest, tmp,
! 				false);
    if (!tmp)
      return NULL_RTX;
  
*************** delete_null_pointer_checks_1 (block_reg,
*** 6047,6053 ****
  	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)
--- 6049,6055 ----
  	continue;
  
        /* LAST_INSN is a conditional jump.  Get its condition.  */
!       condition = get_condition (last_insn, &earliest, false);
  
        /* If we can't determine the condition then skip.  */
        if (! condition)
*************** delete_null_pointer_checks (f)
*** 6173,6179 ****
  	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 an equality
  	 comparison against zero then there's nothing we can do.  */
--- 6175,6181 ----
  	continue;
  
        /* LAST_INSN is a conditional jump.  Get its condition.  */
!       condition = get_condition (last_insn, &earliest, false);
  
        /* If we were unable to get the condition, or it is not an equality
  	 comparison against zero then there's nothing we can do.  */
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.115
diff -c -3 -p -r1.115 ifcvt.c
*** ifcvt.c	14 Apr 2003 21:44:36 -0000	1.115
--- ifcvt.c	24 May 2003 06:35:29 -0000
*************** noce_get_alt_condition (if_info, target,
*** 1391,1397 ****
      }
  
    cond = canonicalize_condition (if_info->jump, cond, reverse,
! 				 earliest, target);
    if (! cond || ! reg_mentioned_p (target, cond))
      return NULL;
  
--- 1391,1397 ----
      }
  
    cond = canonicalize_condition (if_info->jump, cond, reverse,
! 				 earliest, target, false);
    if (! cond || ! reg_mentioned_p (target, cond))
      return NULL;
  
*************** noce_get_condition (jump, earliest)
*** 1669,1675 ****
    /* Otherwise, fall back on canonicalize_condition to do the dirty
       work of manipulating MODE_CC values and COMPARE rtx codes.  */
  
!   tmp = canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX);
    if (!tmp)
      return NULL_RTX;
  
--- 1669,1676 ----
    /* Otherwise, fall back on canonicalize_condition to do the dirty
       work of manipulating MODE_CC values and COMPARE rtx codes.  */
  
!   tmp = canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX,
! 				false);
    if (!tmp)
      return NULL_RTX;
  
*************** noce_get_condition (jump, earliest)
*** 1688,1694 ****
    tmp = XEXP (tmp, 0);
    if (!REG_P (tmp) || GET_MODE_CLASS (GET_MODE (tmp)) != MODE_INT)
      return NULL_RTX;
!   tmp = canonicalize_condition (jump, cond, reverse, earliest, tmp);
    if (!tmp)
      return NULL_RTX;
  
--- 1689,1696 ----
    tmp = XEXP (tmp, 0);
    if (!REG_P (tmp) || GET_MODE_CLASS (GET_MODE (tmp)) != MODE_INT)
      return NULL_RTX;
!   tmp = canonicalize_condition (jump, cond, reverse, earliest, tmp,
! 				false);
    if (!tmp)
      return NULL_RTX;
  
Index: loop-unswitch.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop-unswitch.c,v
retrieving revision 1.3
diff -c -3 -p -r1.3 loop-unswitch.c
*** loop-unswitch.c	5 Mar 2003 22:05:18 -0000	1.3
--- loop-unswitch.c	24 May 2003 06:35:29 -0000
*************** may_unswitch_on_p (loops, bb, loop, body
*** 146,152 ****
  
    /* Condition must be invariant.  We use just a stupid test of invariantness
       of the condition: all used regs must not be modified inside loop body.  */
!   test = get_condition (bb->end, NULL);
    if (!test)
      return false;
  
--- 146,152 ----
  
    /* Condition must be invariant.  We use just a stupid test of invariantness
       of the condition: all used regs must not be modified inside loop body.  */
!   test = get_condition (bb->end, NULL, true);
    if (!test)
      return false;
  
*************** unswitch_single_loop (loops, loop, cond_
*** 257,263 ****
  	  return;
  	}
  
!       if (!(cond = get_condition (bbs[i]->end, &split_before)))
  	abort ();
        rcond = reversed_condition (cond);
        
--- 257,263 ----
  	  return;
  	}
  
!       if (!(cond = get_condition (bbs[i]->end, &split_before, true)))
  	abort ();
        rcond = reversed_condition (cond);
        
Index: loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop.c,v
retrieving revision 1.456
diff -c -3 -p -r1.456 loop.c
*** loop.c	17 May 2003 01:40:41 -0000	1.456
--- loop.c	24 May 2003 06:35:29 -0000
*************** check_dbra_loop (loop, insn_count)
*** 8133,8139 ****
  
    /* 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))
--- 8133,8139 ----
  
    /* Try to compute whether the compare/branch at the loop end is one or
       two instructions.  */
!   get_condition (jump, &first_compare, false);
    if (first_compare == jump)
      compare_and_branch = 1;
    else if (first_compare == prev_nonnote_insn (jump))
*************** update_reg_last_use (x, insn)
*** 9312,9326 ****
  
     If WANT_REG is nonzero, we wish the condition to be relative to that
     register, if possible.  Therefore, do not canonicalize the condition
!    further.  */
  
  rtx
! canonicalize_condition (insn, cond, reverse, earliest, want_reg)
       rtx insn;
       rtx cond;
       int reverse;
       rtx *earliest;
       rtx want_reg;
  {
    enum rtx_code code;
    rtx prev = insn;
--- 9312,9328 ----
  
     If WANT_REG is nonzero, we wish the condition to be relative to that
     register, if possible.  Therefore, do not canonicalize the condition
!    further.  If ALLOW_CC_MODE, allow the resulting condition compare
!    CC mode register.  */
  
  rtx
! canonicalize_condition (insn, cond, reverse, earliest, want_reg, allow_cc_mode)
       rtx insn;
       rtx cond;
       int reverse;
       rtx *earliest;
       rtx want_reg;
+      int allow_cc_mode;
  {
    enum rtx_code code;
    rtx prev = insn;
*************** canonicalize_condition (insn, cond, reve
*** 9499,9512 ****
  
    /* If OP0 is the result of a comparison, we weren't able to find what
       was really being compared, so fail.  */
!   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
      return 0;
  
    /* Canonicalize any ordered comparison with integers involving equality
       if we can do computations in the relevant mode and we do not
       overflow.  */
  
!   if (GET_CODE (op1) == CONST_INT
        && GET_MODE (op0) != VOIDmode
        && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
      {
--- 9501,9516 ----
  
    /* If OP0 is the result of a comparison, we weren't able to find what
       was really being compared, so fail.  */
!   if (!allow_cc_mode
!       && GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
      return 0;
  
    /* Canonicalize any ordered comparison with integers involving equality
       if we can do computations in the relevant mode and we do not
       overflow.  */
  
!   if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_CC
!       && GET_CODE (op1) == CONST_INT
        && GET_MODE (op0) != VOIDmode
        && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
      {
*************** canonicalize_condition (insn, cond, reve
*** 9561,9572 ****
     If EARLIEST is nonzero, 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 (jump, earliest)
       rtx jump;
       rtx *earliest;
  {
    rtx cond;
    int reverse;
--- 9565,9580 ----
     If EARLIEST is nonzero, 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.
!    
!    If ALLOW_CC_MODE, allow the condition returned to compare CC mode
!    register.  */
  
  rtx
! get_condition (jump, earliest, allow_cc_mode)
       rtx jump;
       rtx *earliest;
+      int allow_cc_mode;
  {
    rtx cond;
    int reverse;
*************** get_condition (jump, earliest)
*** 9586,9592 ****
      = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
        && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump);
  
!   return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX);
  }
  
  /* Similar to above routine, except that we also put an invariant last
--- 9594,9601 ----
      = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
        && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump);
  
!   return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX,
! 				 allow_cc_mode);
  }
  
  /* Similar to above routine, except that we also put an invariant last
*************** get_condition_for_loop (loop, x)
*** 9597,9603 ****
       const struct loop *loop;
       rtx x;
  {
!   rtx comparison = get_condition (x, (rtx*) 0);
  
    if (comparison == 0
        || ! loop_invariant_p (loop, XEXP (comparison, 0))
--- 9606,9612 ----
       const struct loop *loop;
       rtx x;
  {
!   rtx comparison = get_condition (x, (rtx*) 0, false);
  
    if (comparison == 0
        || ! loop_invariant_p (loop, XEXP (comparison, 0))
Index: predict.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/predict.c,v
retrieving revision 1.89
diff -c -3 -p -r1.89 predict.c
*** predict.c	23 Apr 2003 14:05:11 -0000	1.89
--- predict.c	24 May 2003 06:35:29 -0000
*************** estimate_probability (loops_info)
*** 549,555 ****
  	    }
  	}
  
!       cond = get_condition (last_insn, &earliest);
        if (! cond)
  	continue;
  
--- 549,555 ----
  	    }
  	}
  
!       cond = get_condition (last_insn, &earliest, false);
        if (! cond)
  	continue;
  
*************** expected_value_to_br_prob ()
*** 705,711 ****
  		(lt r70, r71)
  	 Could use cselib to try and reduce this further.  */
        cond = XEXP (SET_SRC (pc_set (insn)), 0);
!       cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg);
        if (! cond || XEXP (cond, 0) != ev_reg
  	  || GET_CODE (XEXP (cond, 1)) != CONST_INT)
  	continue;
--- 705,711 ----
  		(lt r70, r71)
  	 Could use cselib to try and reduce this further.  */
        cond = XEXP (SET_SRC (pc_set (insn)), 0);
!       cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg, false);
        if (! cond || XEXP (cond, 0) != ev_reg
  	  || GET_CODE (XEXP (cond, 1)) != CONST_INT)
  	continue;


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