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]

Re: unroller bug


Michael Hayes writes:
 > This patch ensures that a canonical comparison is generated.  
 > However, it doesn't appear to fix the problem you had :-(

This patch supercedes the previous patch.  It fixes a dumb mistake
and the function you sent me appears to unroll OK now.

Michael.

Sun Jan  3 22:58:15 1999  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>

	* optabs.c (emit_cmp_insn): Abort if asked to emit non-canonical RTL.
	(emit_cmp_and_jump_insns): New function.
	* epxr.h (emit_cmp_and_jump_insns): Prototype it.
	* loop.c (check_dbra_loop): Use it to replace calls
	to emit_cmp_insn and emit_jump_insn and to canonicalise
	the comparison if necessary.
	* unroll.c (unroll_loop): Likewise.

Index: optabs.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/optabs.c,v
retrieving revision 1.19
diff -c -3 -p -r1.19 optabs.c
*** optabs.c	1998/12/16 20:57:27	1.19
--- optabs.c	1999/01/03 09:59:38
*************** emit_cmp_insn (x, y, comparison, size, m
*** 2722,2727 ****
--- 2722,2731 ----
    if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
      y = force_reg (mode, y);
  
+   /* Abort if we have a non-canonical comparison.  */
+   if (CONSTANT_P (x) && ! CONSTANT_P (y))
+     abort();
+ 
    /* Don't let both operands fail to indicate the mode.  */
    if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
      x = force_reg (mode, x);
*************** emit_cmp_insn (x, y, comparison, size, m
*** 2912,2917 ****
--- 2916,2967 ----
    else
      abort ();
  }
+ 
+ /* Generate code to compare X with Y so that the condition codes are
+    set and to jump to LABEL if the condition is true.  If X is a
+    constant and Y is not a constant, then the comparison is swapped to
+    ensure that the comparison RTL has the canonical form.
+ 
+    MODE is the mode of the inputs (in case they are const_int).
+    UNSIGNEDP nonzero says that X and Y are unsigned;
+    this matters if they need to be widened.
+ 
+    If they have mode BLKmode, then SIZE specifies the size of both X and Y,
+    and ALIGN specifies the known shared alignment of X and Y.
+ 
+    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
+    It is ignored for fixed-point and block comparisons;
+    it is used only for floating-point comparisons.  */
+ 
+ void
+ emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
+      rtx x, y;
+      enum rtx_code comparison;
+      rtx size;
+      enum machine_mode mode;
+      int unsignedp;
+      int align;
+      rtx label;
+ {
+   rtx op0;
+   rtx op1;
+ 	  
+   if (GET_CODE (x) == CONST_INT)
+     {
+       /* Swap operands and condition to ensure canonical RTL.  */
+       op0 = y;
+       op1 = x;
+       comparison = swap_condition (comparison);
+     }
+   else
+     {
+       op0 = x;
+       op1 = y;
+     }
+   emit_cmp_insn (op0, op1, comparison, size, mode, unsignedp, align);
+   emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
+ }
+ 
  
  /* Nonzero if a compare of mode MODE can be done straightforwardly
     (without splitting it into pieces).  */
Index: expr.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expr.h,v
retrieving revision 1.28
diff -c -3 -p -r1.28 expr.h
*** expr.h	1998/12/16 20:55:22	1.28
--- expr.h	1999/01/03 09:59:38
*************** extern void emit_0_to_1_insn PROTO((rtx)
*** 614,619 ****
--- 614,624 ----
  extern void emit_cmp_insn PROTO((rtx, rtx, enum rtx_code, rtx,
  				 enum machine_mode, int, int));
  
+ /* Emit a pair of rtl insns to compare two rtx's and to jump 
+    to a label if the comparison is true.  */
+ extern void emit_cmp_and_jump_insns PROTO((rtx, rtx, enum rtx_code, rtx,
+ 					   enum machine_mode, int, int, rtx));
+ 
  /* Nonzero if a compare of mode MODE can be done straightforwardly
     (without splitting it into pieces).  */
  extern int can_compare_p PROTO((enum machine_mode));
Index: loop.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/loop.c,v
retrieving revision 1.110
diff -c -3 -p -r1.110 loop.c
*** loop.c	1998/12/30 21:51:53	1.110
--- loop.c	1999/01/03 09:59:41
*************** check_dbra_loop (loop_end, insn_count, l
*** 7072,7081 ****
  
  	      /* Add new compare/branch insn at end of loop.  */
  	      start_sequence ();
! 	      emit_cmp_insn (reg, const0_rtx, cmp_code, NULL_RTX,
! 			     GET_MODE (reg), 0, 0);
! 	      emit_jump_insn ((*bcc_gen_fctn[(int) cmp_code])
! 			      (XEXP (jump_label, 0)));
  	      tem = gen_sequence ();
  	      end_sequence ();
  	      emit_jump_insn_before (tem, loop_end);
--- 7072,7080 ----
  
  	      /* Add new compare/branch insn at end of loop.  */
  	      start_sequence ();
! 	      emit_cmp_and_jump_insns (reg, const0_rtx, cmp_code, NULL_RTX,
! 				       GET_MODE (reg), 0, 0, 
! 				       XEXP (jump_label, 0));
  	      tem = gen_sequence ();
  	      end_sequence ();
  	      emit_jump_insn_before (tem, loop_end);
Index: unroll.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/unroll.c,v
retrieving revision 1.39
diff -c -3 -p -r1.39 unroll.c
*** unroll.c	1998/12/16 20:58:43	1.39
--- unroll.c	1999/01/03 09:59:42
*************** unroll_loop (loop_end, insn_count, loop_
*** 919,930 ****
  
  	  if (loop_info->comparison_code != NE)
  	    {
! 	      emit_cmp_insn (initial_value, final_value, neg_inc ? LE : GE,
! 			     NULL_RTX, mode, 0, 0);
! 	      if (neg_inc)
! 		emit_jump_insn (gen_ble (labels[1]));
! 	      else
! 		emit_jump_insn (gen_bge (labels[1]));
  	      JUMP_LABEL (get_last_insn ()) = labels[1];
  	      LABEL_NUSES (labels[1])++;
  	    }
--- 919,927 ----
  
  	  if (loop_info->comparison_code != NE)
  	    {
! 	      emit_cmp_and_jump_insns (initial_value, final_value, 
! 				       neg_inc ? LE : GE,
! 				       NULL_RTX, mode, 0, 0, labels[1]);
  	      JUMP_LABEL (get_last_insn ()) = labels[1];
  	      LABEL_NUSES (labels[1])++;
  	    }
*************** unroll_loop (loop_end, insn_count, loop_
*** 964,979 ****
  		  cmp_const = i;
  		  cmp_code = LE;
  		}
- 
- 	      emit_cmp_insn (diff, GEN_INT (abs_inc * cmp_const),
- 			     cmp_code, NULL_RTX, mode, 0, 0);
  
! 	      if (i == 0)
! 		emit_jump_insn (gen_beq (labels[i]));
! 	      else if (neg_inc)
! 		emit_jump_insn (gen_bge (labels[i]));
! 	      else
! 		emit_jump_insn (gen_ble (labels[i]));
  	      JUMP_LABEL (get_last_insn ()) = labels[i];
  	      LABEL_NUSES (labels[i])++;
  	    }
--- 961,970 ----
  		  cmp_const = i;
  		  cmp_code = LE;
  		}
  
! 	      emit_cmp_and_jump_insns (diff, GEN_INT (abs_inc * cmp_const),
! 				       cmp_code, NULL_RTX, mode, 0, 0,
! 				       labels[i]);
  	      JUMP_LABEL (get_last_insn ()) = labels[i];
  	      LABEL_NUSES (labels[i])++;
  	    }
*************** unroll_loop (loop_end, insn_count, loop_
*** 1002,1015 ****
  		  cmp_const = abs_inc * (unroll_number - 1) + 1;
  		  cmp_code = GE;
  		}
- 
- 	      emit_cmp_insn (diff, GEN_INT (cmp_const), cmp_code, NULL_RTX,
- 			     mode, 0, 0);
  
! 	      if (neg_inc)
! 		emit_jump_insn (gen_ble (labels[0]));
! 	      else
! 		emit_jump_insn (gen_bge (labels[0]));
  	      JUMP_LABEL (get_last_insn ()) = labels[0];
  	      LABEL_NUSES (labels[0])++;
  	    }
--- 993,1001 ----
  		  cmp_const = abs_inc * (unroll_number - 1) + 1;
  		  cmp_code = GE;
  		}
  
! 	      emit_cmp_and_jump_insns (diff, GEN_INT (cmp_const), cmp_code,
! 				       NULL_RTX, mode, 0, 0, labels[0]);
  	      JUMP_LABEL (get_last_insn ()) = labels[0];
  	      LABEL_NUSES (labels[0])++;
  	    }


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