Fix ifcvt on memory operands
Jan Hubicka
jh@suse.cz
Tue Jan 7 21:58:00 GMT 2003
> 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:
More information about the Gcc-patches
mailing list