alias.c (mode_alias_check): New function.
* alias.c (mode_alias_check): New function. (true_dependence, anti_dependence, output_dependence): Call mode_alias_check. From-SVN: r19357
This commit is contained in:
parent
f7554e8cff
commit
d09c938561
@ -1,3 +1,9 @@
|
|||||||
|
Tue Apr 21 16:36:01 1998 John Carr <jfc@mit.edu>
|
||||||
|
|
||||||
|
* alias.c (mode_alias_check): New function.
|
||||||
|
(true_dependence, anti_dependence, output_dependence): Call
|
||||||
|
mode_alias_check.
|
||||||
|
|
||||||
Tue Apr 21 12:05:32 1998 Jeffrey A Law (law@cygnus.com)
|
Tue Apr 21 12:05:32 1998 Jeffrey A Law (law@cygnus.com)
|
||||||
|
|
||||||
* c-common.c (type_for_mode): Handle TI types.
|
* c-common.c (type_for_mode): Handle TI types.
|
||||||
|
128
gcc/alias.c
128
gcc/alias.c
@ -35,6 +35,7 @@ static int memrefs_conflict_p PROTO((int, rtx, int, rtx,
|
|||||||
static void record_set PROTO((rtx, rtx));
|
static void record_set PROTO((rtx, rtx));
|
||||||
static rtx find_base_term PROTO((rtx));
|
static rtx find_base_term PROTO((rtx));
|
||||||
static int base_alias_check PROTO((rtx, rtx));
|
static int base_alias_check PROTO((rtx, rtx));
|
||||||
|
static int mode_alias_check PROTO((rtx, rtx, int (*)(rtx)));
|
||||||
|
|
||||||
/* Set up all info needed to perform alias analysis on memory references. */
|
/* Set up all info needed to perform alias analysis on memory references. */
|
||||||
|
|
||||||
@ -633,7 +634,11 @@ base_alias_check (x, y)
|
|||||||
align memory references, as is done on the Alpha.
|
align memory references, as is done on the Alpha.
|
||||||
|
|
||||||
Nice to notice that varying addresses cannot conflict with fp if no
|
Nice to notice that varying addresses cannot conflict with fp if no
|
||||||
local variables had their addresses taken, but that's too hard now. */
|
local variables had their addresses taken, but that's too hard now.
|
||||||
|
|
||||||
|
TODO: (symbol_ref foo) can not alias (plus REG N) if N is a positive
|
||||||
|
integer because REG would have to point outside of the object, which
|
||||||
|
is not allowed in C or C++. */
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -815,6 +820,64 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
|
|||||||
generate aligned addresses from unaligned addresses, for instance, the
|
generate aligned addresses from unaligned addresses, for instance, the
|
||||||
alpha storeqi_unaligned pattern. */
|
alpha storeqi_unaligned pattern. */
|
||||||
|
|
||||||
|
|
||||||
|
/* This subroutine implements the type and struct/varying part of the
|
||||||
|
alias check.
|
||||||
|
|
||||||
|
Return 0 if the memory references can never alias.
|
||||||
|
Return 1 if the values of the addresses should be checked. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
mode_alias_check (x, y, varies)
|
||||||
|
register rtx x, y;
|
||||||
|
int (*varies) PROTO ((rtx));
|
||||||
|
{
|
||||||
|
enum machine_mode x_mode = GET_MODE (x), y_mode = GET_MODE (y);
|
||||||
|
rtx x_addr = XEXP (x, 0), y_addr = XEXP (y, 0);
|
||||||
|
int x_varies, y_varies, x_struct, y_struct;
|
||||||
|
|
||||||
|
/* If either address is an AND then neither the mode check nor the
|
||||||
|
struct/varying check is valid. */
|
||||||
|
if (GET_CODE (x_addr) == AND || GET_CODE (y_addr) == AND)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
x_struct = MEM_IN_STRUCT_P (x);
|
||||||
|
y_struct = MEM_IN_STRUCT_P (y);
|
||||||
|
|
||||||
|
/* QImode and BLKmode references can alias anything. */
|
||||||
|
if (x_mode == QImode || x_mode == BLKmode
|
||||||
|
|| y_mode == QImode || y_mode == BLKmode)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Otherwise, different modes can only alias if they are structure
|
||||||
|
references. gcc bitfield operations can access an entire word,
|
||||||
|
but that word may also contain integers accessed directly.
|
||||||
|
|
||||||
|
??? It appears that bitfield accesses can not be larger than
|
||||||
|
word_mode?
|
||||||
|
??? Can complex modes alias their components? */
|
||||||
|
if (x_mode != y_mode && ! (x_struct && y_struct))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Modes are the same or may alias. */
|
||||||
|
|
||||||
|
/* No alias if one reference is a struct at a varying address and the
|
||||||
|
other is a scalar at a fixed address.
|
||||||
|
|
||||||
|
If either reference is a varying scalar or a fixed struct nothing
|
||||||
|
is known about aliasing. */
|
||||||
|
x_varies = varies (x_addr);
|
||||||
|
if (x_struct != x_varies)
|
||||||
|
return 1;
|
||||||
|
y_varies = varies (y_addr);
|
||||||
|
if (y_struct != y_varies)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Both are varying structs or fixed scalars. Check that they are not
|
||||||
|
the same type. */
|
||||||
|
return (x_struct == y_struct);
|
||||||
|
}
|
||||||
|
|
||||||
/* Read dependence: X is read after read in MEM takes place. There can
|
/* Read dependence: X is read after read in MEM takes place. There can
|
||||||
only be a dependence here if both reads are volatile. */
|
only be a dependence here if both reads are volatile. */
|
||||||
|
|
||||||
@ -853,40 +916,17 @@ true_dependence (mem, mem_mode, x, varies)
|
|||||||
if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0)))
|
if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (! mode_alias_check (x, mem, varies))
|
||||||
|
return 0;
|
||||||
|
|
||||||
x_addr = canon_rtx (XEXP (x, 0));
|
x_addr = canon_rtx (XEXP (x, 0));
|
||||||
mem_addr = canon_rtx (XEXP (mem, 0));
|
mem_addr = canon_rtx (XEXP (mem, 0));
|
||||||
|
|
||||||
if (mem_mode == VOIDmode)
|
if (mem_mode == VOIDmode)
|
||||||
mem_mode = GET_MODE (mem);
|
mem_mode = GET_MODE (mem);
|
||||||
|
|
||||||
if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
|
return memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
|
||||||
SIZE_FOR_MODE (x), x_addr, 0))
|
SIZE_FOR_MODE (x), x_addr, 0);
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* If both references are struct references, or both are not, nothing
|
|
||||||
is known about aliasing.
|
|
||||||
|
|
||||||
If either reference is QImode or BLKmode, ANSI C permits aliasing.
|
|
||||||
|
|
||||||
If both addresses are constant, or both are not, nothing is known
|
|
||||||
about aliasing. */
|
|
||||||
if (MEM_IN_STRUCT_P (x) == MEM_IN_STRUCT_P (mem)
|
|
||||||
|| mem_mode == QImode || mem_mode == BLKmode
|
|
||||||
|| GET_MODE (x) == QImode || GET_MODE (x) == BLKmode
|
|
||||||
|| GET_CODE (x_addr) == AND || GET_CODE (mem_addr) == AND
|
|
||||||
|| varies (x_addr) == varies (mem_addr))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* One memory reference is to a constant address, one is not.
|
|
||||||
One is to a structure, the other is not.
|
|
||||||
|
|
||||||
If either memory reference is a variable structure the other is a
|
|
||||||
fixed scalar and there is no aliasing. */
|
|
||||||
if ((MEM_IN_STRUCT_P (mem) && varies (mem_addr))
|
|
||||||
|| (MEM_IN_STRUCT_P (x) && varies (x_addr)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Anti dependence: X is written after read in MEM takes place. */
|
/* Anti dependence: X is written after read in MEM takes place. */
|
||||||
@ -916,16 +956,11 @@ anti_dependence (mem, x)
|
|||||||
x_addr = XEXP (x, 0);
|
x_addr = XEXP (x, 0);
|
||||||
mem_addr = XEXP (mem, 0);
|
mem_addr = XEXP (mem, 0);
|
||||||
|
|
||||||
return (memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
|
if (! mode_alias_check (x, mem, rtx_varies_p))
|
||||||
SIZE_FOR_MODE (x), x_addr, 0)
|
return 0;
|
||||||
&& ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)
|
|
||||||
&& GET_MODE (mem) != QImode
|
return memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
|
||||||
&& GET_CODE (mem_addr) != AND
|
SIZE_FOR_MODE (x), x_addr, 0);
|
||||||
&& ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x))
|
|
||||||
&& ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x)
|
|
||||||
&& GET_MODE (x) != QImode
|
|
||||||
&& GET_CODE (x_addr) != AND
|
|
||||||
&& ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output dependence: X is written after store in MEM takes place. */
|
/* Output dependence: X is written after store in MEM takes place. */
|
||||||
@ -944,16 +979,11 @@ output_dependence (mem, x)
|
|||||||
x = canon_rtx (x);
|
x = canon_rtx (x);
|
||||||
mem = canon_rtx (mem);
|
mem = canon_rtx (mem);
|
||||||
|
|
||||||
return (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0),
|
if (! mode_alias_check (x, mem, rtx_varies_p))
|
||||||
SIZE_FOR_MODE (x), XEXP (x, 0), 0)
|
return 0;
|
||||||
&& ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem)
|
|
||||||
&& GET_MODE (mem) != QImode
|
return memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0),
|
||||||
&& GET_CODE (XEXP (mem, 0)) != AND
|
SIZE_FOR_MODE (x), XEXP (x, 0), 0);
|
||||||
&& ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x))
|
|
||||||
&& ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x)
|
|
||||||
&& GET_MODE (x) != QImode
|
|
||||||
&& GET_CODE (XEXP (x, 0)) != AND
|
|
||||||
&& ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user