Commit 15750b1e authored by wehle's avatar wehle
Browse files

* i386.c (ix86_find_base_term): New.

	* i386-protos.h (ix86_find_base_term): Prototype.
	* i386.h (FIND_BASE_TERM): Define.
	* alias.c (find_base_term): Use it.
	* tm.texi (FIND_BASE_TERM): Document it.

	* alias.c (true_dependence, write_dependence_p): Unchanging
	memory can't conflict with non-unchanging memory.

	* alias.c (memrefs_conflict_p): A BLKmode reference
	to a symbol (or CONST_INT address) always conflicts
	with a reference to another symbol.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35985 138bc75d-0d04-0410-961f-82ee72b054a4
parent e4a999f8
Fri Aug 25 12:52:49 EDT 2000 John Wehle (john@feith.com)
* i386.c (ix86_find_base_term): New.
* i386-protos.h (ix86_find_base_term): Prototype.
* i386.h (FIND_BASE_TERM): Define.
* alias.c (find_base_term): Use it.
* tm.texi (FIND_BASE_TERM): Document it.
* alias.c (true_dependence, write_dependence_p): Unchanging
memory can't conflict with non-unchanging memory.
* alias.c (memrefs_conflict_p): A BLKmode reference
to a symbol (or CONST_INT address) always conflicts
with a reference to another symbol.
2000-08-25 Joseph S. Myers <jsm28@cam.ac.uk>
* c-common.c (time_char_table): Don't allow width and flags with
......
......@@ -1033,6 +1033,11 @@ find_base_term (x)
cselib_val *val;
struct elt_loc_list *l;
#if defined (FIND_BASE_TERM)
/* Try machine-dependent ways to find the base term. */
x = FIND_BASE_TERM (x);
#endif
switch (GET_CODE (x))
{
case REG:
......@@ -1078,6 +1083,9 @@ find_base_term (x)
is a shift or multiply, then it must be the index register and the
other operand is the base register. */
if (tmp1 == pic_offset_table_rtx && CONSTANT_P (tmp2))
return find_base_term (tmp2);
/* If either operand is known to be a pointer, then use it
to determine the base term. */
if (REG_P (tmp1) && REGNO_POINTER_FLAG (REGNO (tmp1)))
......@@ -1469,10 +1477,9 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
canon_rtx (XEXP (y, 0)), c);
if (CONSTANT_P (y))
return (xsize < 0 || ysize < 0
return (xsize <= 0 || ysize <= 0
|| (rtx_equal_for_memref_p (x, y)
&& (xsize == 0 || ysize == 0
|| (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))));
&& ((c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))));
return 1;
}
......@@ -1574,14 +1581,14 @@ true_dependence (mem, mem_mode, x, varies)
if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0;
/* If X is an unchanging read, then it can't possibly conflict with any
non-unchanging store. It may conflict with an unchanging write though,
because there may be a single store to this address to initialize it.
Just fall through to the code below to resolve the case where we have
both an unchanging read and an unchanging write. This won't handle all
cases optimally, but the possible performance loss should be
negligible. */
if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem))
/* Unchanging memory can't conflict with non-unchanging memory.
A non-unchanging read can conflict with a non-unchanging write.
An unchanging read can conflict with an unchanging write since
there may be a single store to this address to initialize it.
Just fall through to the code below to resolve potential conflicts.
This won't handle all cases optimally, but the possible performance
loss should be negligible. */
if (RTX_UNCHANGING_P (x) != RTX_UNCHANGING_P (mem))
return 0;
if (mem_mode == VOIDmode)
......@@ -1642,6 +1649,10 @@ write_dependence_p (mem, x, writep)
if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0;
/* Unchanging memory can't conflict with non-unchanging memory. */
if (RTX_UNCHANGING_P (x) != RTX_UNCHANGING_P (mem))
return 0;
/* If MEM is an unchanging read, then it can't possibly conflict with
the store to X, because there is at most one store to MEM, and it must
have occurred somewhere before MEM. */
......
......@@ -111,6 +111,7 @@ extern void ix86_split_ashrdi PARAMS ((rtx *, rtx));
extern void ix86_split_lshrdi PARAMS ((rtx *, rtx));
extern void ix86_expand_strlensi_unroll_1 PARAMS ((rtx, rtx, rtx));
extern int ix86_address_cost PARAMS ((rtx));
extern rtx ix86_find_base_term PARAMS ((rtx));
extern rtx assign_386_stack_local PARAMS ((enum machine_mode, int));
extern int ix86_attr_length_immediate_default PARAMS ((rtx, int));
......
......@@ -2332,6 +2332,40 @@ ix86_address_cost (x)
return cost;
}
/* If X is a machine specific address (i.e. a symbol or label being
referenced as a displacement from the GOT implemented using an
UNSPEC), then return the base term. Otherwise return X. */
rtx
ix86_find_base_term (x)
rtx x;
{
rtx term;
if (GET_CODE (x) != PLUS
|| XEXP (x, 0) != pic_offset_table_rtx
|| GET_CODE (XEXP (x, 1)) != CONST)
return x;
term = XEXP (XEXP (x, 1), 0);
if (GET_CODE (term) == PLUS && GET_CODE (XEXP (term, 1)) == CONST_INT)
term = XEXP (term, 0);
if (GET_CODE (term) != UNSPEC
|| XVECLEN (term, 0) != 1
|| XINT (term, 1) != 7)
return x;
term = XVECEXP (term, 0, 0);
if (GET_CODE (term) != SYMBOL_REF
&& GET_CODE (term) != LABEL_REF)
return x;
return term;
}
/* Determine if a given CONST RTX is a valid memory displacement
in PIC mode. */
......
......@@ -1659,6 +1659,17 @@ pop{l} %0" \
#endif
/* If defined, a C expression to determine the base term of address X.
This macro is used in only one place: `find_base_term' in alias.c.
It is always safe for this macro to not be defined. It exists so
that alias analysis can understand machine-dependent addresses.
The typical use of this macro is to handle addresses containing
a label_ref or symbol_ref within an UNSPEC. */
#define FIND_BASE_TERM(X) ix86_find_base_term (x)
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address.
This macro is used in only one place: `memory_address' in explow.c.
......
......@@ -4453,6 +4453,17 @@ may serve in each capacity. The compiler will try both labelings,
looking for one that is valid, and will reload one or both registers
only if neither labeling works.
@findex FIND_BASE_TERM
@item FIND_BASE_TERM (@var{x})
A C expression to determine the base term of address @var{x}.
This macro is used in only one place: `find_base_term' in alias.c.
It is always safe for this macro to not be defined. It exists so
that alias analysis can understand machine-dependent addresses.
The typical use of this macro is to handle addresses containing
a label_ref or symbol_ref within an UNSPEC.
@findex LEGITIMIZE_ADDRESS
@item LEGITIMIZE_ADDRESS (@var{x}, @var{oldx}, @var{mode}, @var{win})
A C compound statement that attempts to replace @var{x} with a valid
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment