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]

Extra arg for rtx_varies_p


There's a hack in rtx_varies_p that makes us return 1 for pic_offset_table_rtx.
This is undesirable for alias analysis on ia64; it restricts scheduling of
loads.  This patch adds an extra argument to rtx_varies_p which tells the
function whether it needs to apply this hack or not.

Bootstrapped in i686-linux; compiled SPECint95 on ia64.


Bernd

	* alias.c (fixed_scalar_and_varying_struct): Adjust prototype of
	arg VARIES_P.  Call it with extra arg.
	(true_dependence): Likewise.
	* rtl.h (rtx_addr_can_trap_p): Declare.
	(rtx_varies_p, rtx_addr_varies_p, true_dependence): Update
	prototypes.
	* rtlanal.c (rtx_addr_can_trap_p): No longer static.
	(rtx_varies_p): Accept extra arg FOR_ALIAS; only disallow
	pic offset table register if it's zero.  All callers changed.
	(rtx_addr_varies_p): Accept extra arg FOR_ALIAS; all callers changed.

Index: alias.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/alias.c,v
retrieving revision 1.108
diff -u -p -r1.108 alias.c
--- alias.c	2000/12/15 00:04:28	1.108
+++ alias.c	2001/01/01 16:59:55
@@ -101,7 +101,7 @@ static int insert_subset_children
 static tree find_base_decl            PARAMS ((tree));
 static alias_set_entry get_alias_set_entry PARAMS ((HOST_WIDE_INT));
 static rtx fixed_scalar_and_varying_struct_p PARAMS ((rtx, rtx, rtx, rtx,
-						      int (*) (rtx)));
+						      int (*) (rtx, int)));
 static int aliases_everything_p         PARAMS ((rtx));
 static int write_dependence_p           PARAMS ((rtx, rtx, int));
 static int nonlocal_mentioned_p         PARAMS ((rtx));
@@ -1541,19 +1541,19 @@ static rtx
 fixed_scalar_and_varying_struct_p (mem1, mem2, mem1_addr, mem2_addr, varies_p)
      rtx mem1, mem2;
      rtx mem1_addr, mem2_addr;
-     int (*varies_p) PARAMS ((rtx));
+     int (*varies_p) PARAMS ((rtx, int));
 {
   if (! flag_strict_aliasing)
     return NULL_RTX;

   if (MEM_SCALAR_P (mem1) && MEM_IN_STRUCT_P (mem2)
-      && !varies_p (mem1_addr) && varies_p (mem2_addr))
+      && !varies_p (mem1_addr, 1) && varies_p (mem2_addr, 1))
     /* MEM1 is a scalar at a fixed address; MEM2 is a struct at a
        varying address.  */
     return mem1;

   if (MEM_IN_STRUCT_P (mem1) && MEM_SCALAR_P (mem2)
-      && varies_p (mem1_addr) && !varies_p (mem2_addr))
+      && varies_p (mem1_addr, 1) && !varies_p (mem2_addr, 1))
     /* MEM2 is a scalar at a fixed address; MEM1 is a struct at a
        varying address.  */
     return mem2;
@@ -1583,7 +1583,7 @@ true_dependence (mem, mem_mode, x, varie
      rtx mem;
      enum machine_mode mem_mode;
      rtx x;
-     int (*varies) PARAMS ((rtx));
+     int (*varies) PARAMS ((rtx, int));
 {
   register rtx x_addr, mem_addr;
   rtx base;
Index: cse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cse.c,v
retrieving revision 1.166
diff -u -p -r1.166 cse.c
--- cse.c	2000/11/24 11:36:27	1.166
+++ cse.c	2001/01/01 16:59:58
@@ -2745,7 +2745,7 @@ cse_rtx_varies_p (x)
 	return 0;
     }

-  return rtx_varies_p (x);
+  return rtx_varies_p (x, 0);
 }

 /* Canonicalize an expression:
Index: local-alloc.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/local-alloc.c,v
retrieving revision 1.75
diff -u -p -r1.75 local-alloc.c
--- local-alloc.c	2000/11/30 21:40:33	1.75
+++ local-alloc.c	2001/01/01 16:59:58
@@ -540,7 +540,7 @@ equiv_init_varies_p (x)
       return 0;

     case REG:
-      return reg_equiv[REGNO (x)].replace == 0 && rtx_varies_p (x);
+      return reg_equiv[REGNO (x)].replace == 0 && rtx_varies_p (x, 0);

     case ASM_OPERANDS:
       if (MEM_VOLATILE_P (x))
@@ -604,7 +604,7 @@ equiv_init_movable_p (x, regno)
     case REG:
       return (reg_equiv[REGNO (x)].loop_depth >= reg_equiv[regno].loop_depth
 	      && reg_equiv[REGNO (x)].replace)
-	     || (REG_BASIC_BLOCK (REGNO (x)) < 0 && ! rtx_varies_p (x));
+	     || (REG_BASIC_BLOCK (REGNO (x)) < 0 && ! rtx_varies_p (x, 0));

     case UNSPEC_VOLATILE:
       return 0;
@@ -933,7 +933,7 @@ update_equiv_regs ()
       /* cse sometimes generates function invariants, but doesn't put a
 	 REG_EQUAL note on the insn.  Since this note would be redundant,
          there's no point creating it earlier than here.  */
-      if (! note && ! rtx_varies_p (src))
+      if (! note && ! rtx_varies_p (src, 0))
 	REG_NOTES (insn)
 	  = note = gen_rtx_EXPR_LIST (REG_EQUAL, src, REG_NOTES (insn));

@@ -944,7 +944,7 @@ update_equiv_regs ()

       if (REG_N_SETS (regno) != 1
 	  && (! note
-	      || rtx_varies_p (XEXP (note, 0))
+	      || rtx_varies_p (XEXP (note, 0), 0)
 	      || (reg_equiv[regno].replacement
 		  && ! rtx_equal_p (XEXP (note, 0),
 				    reg_equiv[regno].replacement))))
@@ -958,7 +958,7 @@ update_equiv_regs ()

       /* If this register is known to be equal to a constant, record that
 	 it is always equivalent to the constant.  */
-      if (note && ! rtx_varies_p (XEXP (note, 0)))
+      if (note && ! rtx_varies_p (XEXP (note, 0), 0))
 	PUT_MODE (note, (enum machine_mode) REG_EQUIV);

       /* If this insn introduces a "constant" register, decrease the priority
Index: reload.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload.c,v
retrieving revision 1.137
diff -u -p -r1.137 reload.c
--- reload.c	2000/12/22 01:24:14	1.137
+++ reload.c	2001/01/01 17:00:00
@@ -4431,7 +4431,7 @@ make_memloc (ad, regno)

   /* If TEM might contain a pseudo, we must copy it to avoid
      modifying it when we do the substitution for the reload.  */
-  if (rtx_varies_p (tem))
+  if (rtx_varies_p (tem, 0))
     tem = copy_rtx (tem);

   tem = gen_rtx_MEM (GET_MODE (ad), tem);
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.235
diff -u -p -r1.235 rtl.h
--- rtl.h	2000/12/29 17:35:57	1.235
+++ rtl.h	2001/01/01 17:00:01
@@ -1352,9 +1352,10 @@ extern void set_unique_reg_note
 		       : NULL_RTX)
 #define single_set_1(I) single_set_2 (I, PATTERN (I))

+extern int rtx_addr_can_trap_p		PARAMS ((rtx));
 extern int rtx_unstable_p		PARAMS ((rtx));
-extern int rtx_varies_p			PARAMS ((rtx));
-extern int rtx_addr_varies_p		PARAMS ((rtx));
+extern int rtx_varies_p			PARAMS ((rtx, int));
+extern int rtx_addr_varies_p		PARAMS ((rtx, int));
 extern HOST_WIDE_INT get_integer_term	PARAMS ((rtx));
 extern rtx get_related_value		PARAMS ((rtx));
 extern int reg_mentioned_p		PARAMS ((rtx, rtx));
@@ -1986,7 +1987,7 @@ extern void fancy_abort PARAMS ((const c
 /* In alias.c */
 extern rtx canon_rtx                    PARAMS ((rtx));
 extern int true_dependence		PARAMS ((rtx, enum machine_mode, rtx,
-						int (*)(rtx)));
+						int (*)(rtx, int)));
 extern int read_dependence		PARAMS ((rtx, rtx));
 extern int anti_dependence		PARAMS ((rtx, rtx));
 extern int output_dependence		PARAMS ((rtx, rtx));
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtlanal.c,v
retrieving revision 1.77
diff -u -p -r1.77 rtlanal.c
--- rtlanal.c	2000/12/21 22:15:22	1.77
+++ rtlanal.c	2001/01/01 17:00:01
@@ -25,7 +25,6 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "rtl.h"

-static int rtx_addr_can_trap_p	PARAMS ((rtx));
 static void reg_set_p_1		PARAMS ((rtx, rtx, void *));
 static void insn_dependent_p_1	PARAMS ((rtx, rtx, void *));
 static void reg_set_last_1	PARAMS ((rtx, rtx, void *));
@@ -113,11 +112,14 @@ rtx_unstable_p (x)
 /* Return 1 if X has a value that can vary even between two
    executions of the program.  0 means X can be compared reliably
    against certain constants or near-constants.
+   FOR_ALIAS is nonzero if we are called from alias analysis; if it is
+   zero, we are slightly more conservative.
    The frame pointer and the arg pointer are considered constant.  */

 int
-rtx_varies_p (x)
+rtx_varies_p (x, for_alias)
      rtx x;
+     int for_alias;
 {
   register RTX_CODE code = GET_CODE (x);
   register int i;
@@ -126,7 +128,7 @@ rtx_varies_p (x)
   switch (code)
     {
     case MEM:
-      return ! RTX_UNCHANGING_P (x) || rtx_varies_p (XEXP (x, 0));
+      return ! RTX_UNCHANGING_P (x) || rtx_varies_p (XEXP (x, 0), for_alias);

     case QUEUED:
       return 1;
@@ -146,19 +148,22 @@ rtx_varies_p (x)
       if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
 	  || x == arg_pointer_rtx)
 	return 0;
-#ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
-      /* ??? When call-clobbered, the value is stable modulo the restore
-	 that must happen after a call.  This currently screws up local-alloc
-	 into believing that the restore is not needed.  */
-      if (x == pic_offset_table_rtx)
-	return 0;
+      if (x == pic_offset_table_rtx
+#ifdef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
+	  /* ??? When call-clobbered, the value is stable modulo the restore
+	     that must happen after a call.  This currently screws up
+	     local-alloc into believing that the restore is not needed, so we
+	     must return 0 only if we are called from alias analysis.  */
+	  && for_alias
 #endif
+	  )
+	return 0;
       return 1;

     case LO_SUM:
       /* The operand 0 of a LO_SUM is considered constant
 	 (in fact is it related specifically to operand 1).  */
-      return rtx_varies_p (XEXP (x, 1));
+      return rtx_varies_p (XEXP (x, 1), for_alias);

     case ASM_OPERANDS:
       if (MEM_VOLATILE_P (x))
@@ -174,14 +179,14 @@ rtx_varies_p (x)
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     if (fmt[i] == 'e')
       {
-	if (rtx_varies_p (XEXP (x, i)))
+	if (rtx_varies_p (XEXP (x, i), for_alias))
 	  return 1;
       }
     else if (fmt[i] == 'E')
       {
 	int j;
 	for (j = 0; j < XVECLEN (x, i); j++)
-	  if (rtx_varies_p (XVECEXP (x, i, j)))
+	  if (rtx_varies_p (XVECEXP (x, i, j), for_alias))
 	    return 1;
       }

@@ -190,7 +195,7 @@ rtx_varies_p (x)

 /* Return 0 if the use of X as an address in a MEM can cause a trap.  */

-static int
+int
 rtx_addr_can_trap_p (x)
      register rtx x;
 {
@@ -236,11 +241,14 @@ rtx_addr_can_trap_p (x)

 /* Return 1 if X refers to a memory location whose address
    cannot be compared reliably with constant addresses,
-   or if X refers to a BLKmode memory object.  */
+   or if X refers to a BLKmode memory object.
+   FOR_ALIAS is nonzero if we are called from alias analysis; if it is
+   zero, we are slightly more conservative.  */

 int
-rtx_addr_varies_p (x)
+rtx_addr_varies_p (x, for_alias)
      rtx x;
+     int for_alias;
 {
   register enum rtx_code code;
   register int i;
@@ -251,20 +259,20 @@ rtx_addr_varies_p (x)

   code = GET_CODE (x);
   if (code == MEM)
-    return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0));
+    return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0), for_alias);

   fmt = GET_RTX_FORMAT (code);
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     if (fmt[i] == 'e')
       {
-	if (rtx_addr_varies_p (XEXP (x, i)))
+	if (rtx_addr_varies_p (XEXP (x, i), for_alias))
 	  return 1;
       }
     else if (fmt[i] == 'E')
       {
 	int j;
 	for (j = 0; j < XVECLEN (x, i); j++)
-	  if (rtx_addr_varies_p (XVECEXP (x, i, j)))
+	  if (rtx_addr_varies_p (XVECEXP (x, i, j), for_alias))
 	    return 1;
       }
   return 0;
Index: config/a29k/a29k.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/a29k/a29k.h,v
retrieving revision 1.16
diff -u -p -r1.16 a29k.h
--- config/a29k/a29k.h	2000/11/02 23:29:07	1.16
+++ config/a29k/a29k.h	2001/01/01 17:00:03
@@ -995,7 +995,7 @@ extern const char *a29k_function_name;
    && ! (needs_regstack_p () && uses_local_reg_p (PATTERN (INSN)))	\
    && (GET_CODE (PATTERN (INSN)) != SET					\
        || GET_CODE (SET_SRC (PATTERN (INSN))) != MEM			\
-       || ! rtx_varies_p (XEXP (SET_SRC (PATTERN (INSN)), 0))))
+       || ! rtx_varies_p (XEXP (SET_SRC (PATTERN (INSN)), 0), 0)))

 /* Output assembler code for a block containing the constant parts
    of a trampoline, leaving space for the variable parts.


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