[bib] cse cleanup wrt address classification

Richard Henderson rth@twiddle.net
Mon Oct 7 04:01:00 GMT 2002


This is the cse patch that depends on the i960 patch 
I posted earlier this evening.

It has built and tested successfully on i686, i960,
alpha, sparc, but I still didn't put it on mainline.
Not yet anyway.


r~


        * cse.c (fixed_base_plus_p): Turn FIXED_BASE_PLUS_P into a
        function; cleanup PLUS case by using recursion.  Update all users.
        (NONZERO_BASE_PLUS_P): Remove.
        (find_comparison_args): Use rtx_addr_can_trap_p instead.
        (fold_rtx): Use nonzero_address_p.
        * rtl.h (nonzero_address_p): Declare.
        * rtlanal.c (rtx_varies_p): Handle ADDRESSOF.
        (rtx_addr_can_trap_p): Likewise.
        (nonzero_address_p): New.
        * simplify-rtx.c (NONZERO_BASE_PLUS_P): Remove.
        (simplify_relational_operation): Use nonzero_address_p.

Index: cse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cse.c,v
retrieving revision 1.238
diff -u -p -r1.238 cse.c
--- cse.c	1 Oct 2002 12:19:36 -0000	1.238
+++ cse.c	7 Oct 2002 08:58:02 -0000
@@ -582,55 +582,7 @@ struct cse_basic_block_data
     } path[PATHLENGTH];
 };
 
-/* Nonzero if X has the form (PLUS frame-pointer integer).  We check for
-   virtual regs here because the simplify_*_operation routines are called
-   by integrate.c, which is called before virtual register instantiation.
-
-   ?!? FIXED_BASE_PLUS_P and NONZERO_BASE_PLUS_P need to move into
-   a header file so that their definitions can be shared with the
-   simplification routines in simplify-rtx.c.  Until then, do not
-   change these macros without also changing the copy in simplify-rtx.c.  */
-
-#define FIXED_BASE_PLUS_P(X)					\
-  ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx	\
-   || ((X) == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])\
-   || (X) == virtual_stack_vars_rtx				\
-   || (X) == virtual_incoming_args_rtx				\
-   || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
-       && (XEXP (X, 0) == frame_pointer_rtx			\
-	   || XEXP (X, 0) == hard_frame_pointer_rtx		\
-	   || ((X) == arg_pointer_rtx				\
-	       && fixed_regs[ARG_POINTER_REGNUM])		\
-	   || XEXP (X, 0) == virtual_stack_vars_rtx		\
-	   || XEXP (X, 0) == virtual_incoming_args_rtx))	\
-   || GET_CODE (X) == ADDRESSOF)
-
-/* Similar, but also allows reference to the stack pointer.
-
-   This used to include FIXED_BASE_PLUS_P, however, we can't assume that
-   arg_pointer_rtx by itself is nonzero, because on at least one machine,
-   the i960, the arg pointer is zero when it is unused.  */
-
-#define NONZERO_BASE_PLUS_P(X)					\
-  ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx	\
-   || (X) == virtual_stack_vars_rtx				\
-   || (X) == virtual_incoming_args_rtx				\
-   || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
-       && (XEXP (X, 0) == frame_pointer_rtx			\
-	   || XEXP (X, 0) == hard_frame_pointer_rtx		\
-	   || ((X) == arg_pointer_rtx				\
-	       && fixed_regs[ARG_POINTER_REGNUM])		\
-	   || XEXP (X, 0) == virtual_stack_vars_rtx		\
-	   || XEXP (X, 0) == virtual_incoming_args_rtx))	\
-   || (X) == stack_pointer_rtx					\
-   || (X) == virtual_stack_dynamic_rtx				\
-   || (X) == virtual_outgoing_args_rtx				\
-   || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
-       && (XEXP (X, 0) == stack_pointer_rtx			\
-	   || XEXP (X, 0) == virtual_stack_dynamic_rtx		\
-	   || XEXP (X, 0) == virtual_outgoing_args_rtx))	\
-   || GET_CODE (X) == ADDRESSOF)
-
+static bool fixed_base_plus_p	PARAMS ((rtx x));
 static int notreg_cost		PARAMS ((rtx, enum rtx_code));
 static int approx_reg_cost_1	PARAMS ((rtx *, void *));
 static int approx_reg_cost	PARAMS ((rtx));
@@ -693,6 +645,39 @@ static bool insn_live_p		PARAMS ((rtx, i
 static bool set_live_p		PARAMS ((rtx, rtx, int *));
 static bool dead_libcall_p	PARAMS ((rtx, int *));
 
+/* Nonzero if X has the form (PLUS frame-pointer integer).  We check for
+   virtual regs here because the simplify_*_operation routines are called
+   by integrate.c, which is called before virtual register instantiation.  */
+
+static bool
+fixed_base_plus_p (x)
+     rtx x;
+{
+  switch (GET_CODE (x))
+    {
+    case REG:
+      if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx)
+	return true;
+      if (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])
+	return true;
+      if (REGNO (x) >= FIRST_VIRTUAL_REGISTER
+	  && REGNO (x) <= LAST_VIRTUAL_REGISTER)
+	return true;
+      return false;
+
+    case PLUS:
+      if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+	return false;
+      return fixed_base_plus_p (XEXP (x, 0));
+
+    case ADDRESSOF:
+      return true;
+
+    default:
+      return false;
+    }
+}
+
 /* Dump the expressions in the equivalence class indicated by CLASSP.
    This function is used only for debugging.  */
 void
@@ -1597,7 +1582,7 @@ insert (x, classp, hash, mode)
 		   || (GET_CODE (x) == REG
 		       && RTX_UNCHANGING_P (x)
 		       && REGNO (x) >= FIRST_PSEUDO_REGISTER)
-		   || FIXED_BASE_PLUS_P (x));
+		   || fixed_base_plus_p (x));
 
   if (table[hash])
     table[hash]->prev_same_hash = elt;
@@ -2359,10 +2344,9 @@ canon_hash (x, mode)
 	  do_not_record = 1;
 	  return 0;
 	}
-      if (! RTX_UNCHANGING_P (x) || FIXED_BASE_PLUS_P (XEXP (x, 0)))
-	{
-	  hash_arg_in_memory = 1;
-	}
+      if (! RTX_UNCHANGING_P (x) || fixed_base_plus_p (XEXP (x, 0)))
+	hash_arg_in_memory = 1;
+
       /* Now that we have already found this special case,
 	 might as well speed it up as much as possible.  */
       hash += (unsigned) MEM;
@@ -2380,7 +2364,7 @@ canon_hash (x, mode)
 	  hash += (unsigned) USE;
 	  x = XEXP (x, 0);
 
-	  if (! RTX_UNCHANGING_P (x) || FIXED_BASE_PLUS_P (XEXP (x, 0)))
+	  if (! RTX_UNCHANGING_P (x) || fixed_base_plus_p (XEXP (x, 0)))
 	    hash_arg_in_memory = 1;
 
 	  /* Now that we have already found this special case,
@@ -3257,9 +3241,10 @@ find_comparison_args (code, parg1, parg2
 	      break;
 	    }
 
-	  /* If this is fp + constant, the equivalent is a better operand since
-	     it may let us predict the value of the comparison.  */
-	  else if (NONZERO_BASE_PLUS_P (p->exp))
+	  /* If this non-trapping address, e.g. fp + constant, the
+	     equivalent is a better operand since it may let us predict
+	     the value of the comparison.  */
+	  else if (!rtx_addr_can_trap_p (p->exp))
 	    {
 	      arg1 = p->exp;
 	      continue;
@@ -3960,17 +3945,10 @@ fold_rtx (x, insn)
 	     comparison.  */
 	  if (const_arg0 == 0 || const_arg1 == 0)
 	    {
-	      /* Is FOLDED_ARG0 frame-pointer plus a constant?  Or
-		 non-explicit constant?  These aren't zero, but we
-		 don't know their sign.  */
+	      /* Some addresses are known to be nonzero.  We don't know
+		 their sign, but equality comparisons are known.  */
 	      if (const_arg1 == const0_rtx
-		  && (NONZERO_BASE_PLUS_P (folded_arg0)
-#if 0  /* Sad to say, on sysvr4, #pragma weak can make a symbol address
-	  come out as 0.  */
-		      || GET_CODE (folded_arg0) == SYMBOL_REF
-#endif
-		      || GET_CODE (folded_arg0) == LABEL_REF
-		      || GET_CODE (folded_arg0) == CONST))
+		  && nonzero_address_p (folded_arg0))
 		{
 		  if (code == EQ)
 		    return false_rtx;
@@ -6164,7 +6142,7 @@ cse_insn (insn, libcall_insn)
 
 	elt->in_memory = (GET_CODE (sets[i].inner_dest) == MEM
 			  && (! RTX_UNCHANGING_P (sets[i].inner_dest)
-			      || FIXED_BASE_PLUS_P (XEXP (sets[i].inner_dest,
+			      || fixed_base_plus_p (XEXP (sets[i].inner_dest,
 							  0))));
 
 	/* If we have (set (subreg:m1 (reg:m2 foo) 0) (bar:m1)), M1 is no
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.372
diff -u -p -r1.372 rtl.h
--- rtl.h	30 Sep 2002 19:35:17 -0000	1.372
+++ rtl.h	7 Oct 2002 08:58:03 -0000
@@ -1576,6 +1576,7 @@ extern rtx set_unique_reg_note		PARAMS (
 #define single_set_1(I) single_set_2 (I, PATTERN (I))
 
 extern int rtx_addr_can_trap_p		PARAMS ((rtx));
+extern bool nonzero_address_p		PARAMS ((rtx));
 extern int rtx_unstable_p		PARAMS ((rtx));
 extern int rtx_varies_p			PARAMS ((rtx, int));
 extern int rtx_addr_varies_p		PARAMS ((rtx, int));
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtlanal.c,v
retrieving revision 1.140
diff -u -p -r1.140 rtlanal.c
--- rtlanal.c	26 Sep 2002 22:25:14 -0000	1.140
+++ rtlanal.c	7 Oct 2002 08:58:04 -0000
@@ -153,6 +153,10 @@ rtx_varies_p (x, for_alias)
     case LABEL_REF:
       return 0;
 
+    case ADDRESSOF:
+      /* This will resolve to some offset from the frame pointer.  */
+      return 0;
+
     case REG:
       /* Note that we have to test for the actual rtx used for the frame
 	 and arg pointers and not just the register number in case we have
@@ -225,6 +229,10 @@ rtx_addr_can_trap_p (x)
     case LABEL_REF:
       return 0;
 
+    case ADDRESSOF:
+      /* This will resolve to some offset from the frame pointer.  */
+      return 0;
+
     case REG:
       /* As in rtx_varies_p, we have to use the actual rtx, not reg number.  */
       if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
@@ -267,6 +275,90 @@ rtx_addr_can_trap_p (x)
 
   /* If it isn't one of the case above, it can cause a trap.  */
   return 1;
+}
+
+/* Return true if X is an address that is known to not be zero.  */
+
+bool
+nonzero_address_p (x)
+     rtx x;
+{
+  enum rtx_code code = GET_CODE (x);
+
+  switch (code)
+    {
+    case SYMBOL_REF:
+      return !SYMBOL_REF_WEAK (x);
+
+    case LABEL_REF:
+      return true;
+
+    case ADDRESSOF:
+      /* This will resolve to some offset from the frame pointer.  */
+      return true;
+
+    case REG:
+      /* As in rtx_varies_p, we have to use the actual rtx, not reg number.  */
+      if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
+	  || x == stack_pointer_rtx
+	  || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]))
+	return true;
+      /* All of the virtual frame registers are stack references.  */
+      if (REGNO (x) >= FIRST_VIRTUAL_REGISTER
+	  && REGNO (x) <= LAST_VIRTUAL_REGISTER)
+	return true;
+      return false;
+
+    case CONST:
+      return nonzero_address_p (XEXP (x, 0));
+
+    case PLUS:
+      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+	{
+	  /* Pointers aren't allowed to wrap.  If we've got a register
+	     that is known to be a pointer, and a positive offset, then
+	     the composite can't be zero.  */
+	  if (INTVAL (XEXP (x, 1)) > 0
+	      && REG_P (XEXP (x, 0))
+	      && REG_POINTER (XEXP (x, 0)))
+	    return true;
+
+	  return nonzero_address_p (XEXP (x, 0));
+	}
+      /* Handle PIC references.  */
+      else if (XEXP (x, 0) == pic_offset_table_rtx
+	       && CONSTANT_P (XEXP (x, 1)))
+	return true;
+      return false;
+
+    case PRE_MODIFY:
+      /* Similar to the above; allow positive offsets.  Further, since
+	 auto-inc is only allowed in memories, the register must be a
+	 pointer.  */
+      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+	  && INTVAL (XEXP (x, 1)) > 0)
+	return true;
+      return nonzero_address_p (XEXP (x, 0));
+
+    case PRE_INC:
+      /* Similarly.  Further, the offset is always positive.  */
+      return true;
+
+    case PRE_DEC:
+    case POST_DEC:
+    case POST_INC:
+    case POST_MODIFY:
+      return nonzero_address_p (XEXP (x, 0));
+
+    case LO_SUM:
+      return nonzero_address_p (XEXP (x, 1));
+
+    default:
+      break;
+    }
+
+  /* If it isn't one of the case above, might be zero.  */
+  return false;
 }
 
 /* Return 1 if X refers to a memory location whose address
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.122
diff -u -p -r1.122 simplify-rtx.c
--- simplify-rtx.c	27 Sep 2002 12:48:02 -0000	1.122
+++ simplify-rtx.c	7 Oct 2002 08:58:04 -0000
@@ -39,41 +39,6 @@ Software Foundation, 59 Temple Place - S
 
 /* Simplification and canonicalization of RTL.  */
 
-/* Nonzero if X has the form (PLUS frame-pointer integer).  We check for
-   virtual regs here because the simplify_*_operation routines are called
-   by integrate.c, which is called before virtual register instantiation.
-
-   ?!? NONZERO_BASE_PLUS_P needs to move into
-   a header file so that their definitions can be shared with the
-   simplification routines in simplify-rtx.c.  Until then, do not
-   change this macro without also changing the copy in simplify-rtx.c.  */
-
-/* Allows reference to the stack pointer.
-
-   This used to include FIXED_BASE_PLUS_P, however, we can't assume that
-   arg_pointer_rtx by itself is nonzero, because on at least one machine,
-   the i960, the arg pointer is zero when it is unused.  */
-
-#define NONZERO_BASE_PLUS_P(X)					\
-  ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx	\
-   || (X) == virtual_stack_vars_rtx				\
-   || (X) == virtual_incoming_args_rtx				\
-   || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
-       && (XEXP (X, 0) == frame_pointer_rtx			\
-	   || XEXP (X, 0) == hard_frame_pointer_rtx		\
-	   || ((X) == arg_pointer_rtx				\
-	       && fixed_regs[ARG_POINTER_REGNUM])		\
-	   || XEXP (X, 0) == virtual_stack_vars_rtx		\
-	   || XEXP (X, 0) == virtual_incoming_args_rtx))	\
-   || (X) == stack_pointer_rtx					\
-   || (X) == virtual_stack_dynamic_rtx				\
-   || (X) == virtual_outgoing_args_rtx				\
-   || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
-       && (XEXP (X, 0) == stack_pointer_rtx			\
-	   || XEXP (X, 0) == virtual_stack_dynamic_rtx		\
-	   || XEXP (X, 0) == virtual_outgoing_args_rtx))	\
-   || GET_CODE (X) == ADDRESSOF)
-
 /* Much code operates on (low, high) pairs; the low value is an
    unsigned wide int, the high value a signed wide int.  We
    occasionally need to sign extend from low to high as if low were a
@@ -2022,25 +1987,12 @@ simplify_relational_operation (code, mod
       switch (code)
 	{
 	case EQ:
-	  /* References to the frame plus a constant or labels cannot
-	     be zero, but a SYMBOL_REF can due to #pragma weak.  */
-	  if (((NONZERO_BASE_PLUS_P (op0) && trueop1 == const0_rtx)
-	       || GET_CODE (trueop0) == LABEL_REF)
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-	      /* On some machines, the ap reg can be 0 sometimes.  */
-	      && op0 != arg_pointer_rtx
-#endif
-		)
+	  if (trueop1 == const0_rtx && nonzero_address_p (op0))
 	    return const0_rtx;
 	  break;
 
 	case NE:
-	  if (((NONZERO_BASE_PLUS_P (op0) && trueop1 == const0_rtx)
-	       || GET_CODE (trueop0) == LABEL_REF)
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-	      && op0 != arg_pointer_rtx
-#endif
-	      )
+	  if (trueop1 == const0_rtx && nonzero_address_p (op0))
 	    return const_true_rtx;
 	  break;
 



More information about the Gcc-patches mailing list