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: Fix ifcvt on memory operands


> On Wed, Dec 04, 2002 at 08:35:01PM +0100, Jan Hubicka wrote:
> > +       if (!nonoverlapping_memrefs_p (x, (rtx)data))
> 
> I don't think you should be using nonoverlapping_memrefs_p
> directly.  Use
> 
> 	anti_dependence (x, data) || output_dependence (x, data)
> 
> Or better yet change write_depenence_p to let you do both
> at once.
> 
> > + 	memory_modified = 1;
> 
> 	= true;
> 
> > +   rtx insn;
> > +   if (start == end)
> > +     return 0;
> 
> Whitespace before if.
> 
> >       case MEM:
> > !       if (RTX_UNCHANGING_P (x))
> > ! 	return 0;
> > !       if (modified_between_p (XEXP (x, 0), start, end))
> >   	return 1;
> > +       for (insn = NEXT_INSN (start); insn != end; insn = NEXT_INSN (insn))
> > + 	if (memory_modified_in_insn_p (x, insn))
> > + 	  return 1;
> > +       return 0;
> 
> Why are you checking the address?

Because when the address change, the value of expression does as well.
> 
> You'll need to change the function comment that says that
> alias info isn't used.  ;-)


/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -march=athlon" } */
/* { dg-final { scan-assembler "cmov" } } */

/* Verify that if conversion happends for memory references.  */
int ARCHnodes;
int *nodekind;
float *nodekindf;
t()
{
int i;
/* Redefine nodekind to be 1 for all surface nodes */

  for (i = 0; i < ARCHnodes; i++) {
    nodekind[i] = (int) nodekindf[i];
    if (nodekind[i] == 3)
      nodekind[i] = 1;
  }
}

Tue Jan  7 22:54:09 CET 2003  Jan Hubicka  <jh@suse.cz>

	* alias.c (memory_modified_1): New static function.
	(memory_modified): New static varaible.
	(memory_modified_in_insn_p): New global function.
	* rtl.h (memory_modified_in_insn_p): Declare.
	* rtlanal.c (modified_between_p, modified_in_p): Be smart about memory
	references.

Index: alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alias.c,v
retrieving revision 1.183
diff -c -3 -p -r1.183 alias.c
*** alias.c	24 Dec 2002 15:49:24 -0000	1.183
--- alias.c	7 Jan 2003 21:51:12 -0000
*************** static int nonlocal_referenced_p_1      
*** 118,123 ****
--- 118,124 ----
  static int nonlocal_referenced_p        PARAMS ((rtx));
  static int nonlocal_set_p_1             PARAMS ((rtx *, void *));
  static int nonlocal_set_p               PARAMS ((rtx));
+ static void memory_modified_1		PARAMS ((rtx, rtx, void *));
  
  /* Set up all info needed to perform alias analysis on memory references.  */
  
*************** init_alias_once ()
*** 2699,2704 ****
--- 2700,2734 ----
  #endif
  
    alias_sets = splay_tree_new (splay_tree_compare_ints, 0, 0);
+ }
+ 
+ /* Set MEMORY_MODIFIED when X modifies DATA (that is assumed
+    to be memory reference.  */
+ static bool memory_modified;
+ static void
+ memory_modified_1 (x, pat, data)
+ 	rtx x, pat ATTRIBUTE_UNUSED;
+ 	void *data;
+ {
+   if (GET_CODE (x) == MEM)
+     {
+       if (anti_dependence (x, (rtx)data) || output_dependence (x, (rtx)data))
+ 	memory_modified = true;
+     }
+ }
+ 
+ 
+ /* Return true when INSN possibly modify memory contents of MEM
+    (ie address can be modified).  */
+ bool
+ memory_modified_in_insn_p (mem, insn)
+      rtx mem, insn;
+ {
+   if (!INSN_P (insn))
+     return false;
+   memory_modified = false;
+   note_stores (PATTERN (insn), memory_modified_1, mem);
+   return memory_modified;
  }
  
  /* Initialize the aliasing machinery.  Initialize the REG_KNOWN_VALUE
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtlanal.c,v
retrieving revision 1.142
diff -c -3 -p -r1.142 rtlanal.c
*** rtlanal.c	24 Dec 2002 08:30:30 -0000	1.142
--- rtlanal.c	7 Jan 2003 21:51:23 -0000
*************** regs_set_between_p (x, start, end)
*** 1037,1043 ****
  
  /* Similar to reg_set_between_p, but check all registers in X.  Return 0
     only if none of them are modified between START and END.  Return 1 if
!    X contains a MEM; this routine does not perform any memory aliasing.  */
  
  int
  modified_between_p (x, start, end)
--- 1037,1043 ----
  
  /* Similar to reg_set_between_p, but check all registers in X.  Return 0
     only if none of them are modified between START and END.  Return 1 if
!    X contains a MEM; this routine does usememory aliasing.  */
  
  int
  modified_between_p (x, start, end)
*************** modified_between_p (x, start, end)
*** 1047,1052 ****
--- 1047,1056 ----
    enum rtx_code code = GET_CODE (x);
    const char *fmt;
    int i, j;
+   rtx insn;
+ 
+   if (start == end)
+     return 0;
  
    switch (code)
      {
*************** modified_between_p (x, start, end)
*** 1063,1072 ****
        return 1;
  
      case MEM:
!       /* If the memory is not constant, assume it is modified.  If it is
! 	 constant, we still have to check the address.  */
!       if (! RTX_UNCHANGING_P (x))
  	return 1;
        break;
  
      case REG:
--- 1067,1080 ----
        return 1;
  
      case MEM:
!       if (RTX_UNCHANGING_P (x))
! 	return 0;
!       if (modified_between_p (XEXP (x, 0), start, end))
  	return 1;
+       for (insn = NEXT_INSN (start); insn != end; insn = NEXT_INSN (insn))
+ 	if (memory_modified_in_insn_p (x, insn))
+ 	  return 1;
+       return 0;
        break;
  
      case REG:
*************** modified_between_p (x, start, end)
*** 1093,1099 ****
  
  /* Similar to reg_set_p, but check all registers in X.  Return 0 only if none
     of them are modified in INSN.  Return 1 if X contains a MEM; this routine
!    does not perform any memory aliasing.  */
  
  int
  modified_in_p (x, insn)
--- 1101,1107 ----
  
  /* Similar to reg_set_p, but check all registers in X.  Return 0 only if none
     of them are modified in INSN.  Return 1 if X contains a MEM; this routine
!    does use memory aliasing.  */
  
  int
  modified_in_p (x, insn)
*************** modified_in_p (x, insn)
*** 1119,1128 ****
        return 1;
  
      case MEM:
!       /* If the memory is not constant, assume it is modified.  If it is
! 	 constant, we still have to check the address.  */
!       if (! RTX_UNCHANGING_P (x))
  	return 1;
        break;
  
      case REG:
--- 1127,1139 ----
        return 1;
  
      case MEM:
!       if (RTX_UNCHANGING_P (x))
! 	return 0;
!       if (modified_in_p (XEXP (x, 0), insn))
  	return 1;
+       if (memory_modified_in_insn_p (x, insn))
+ 	return 1;
+       return 0;
        break;
  
      case REG:


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