Commit b949ea8b by John Wehle Committed by John Wehle

i386.c (ix86_find_base_term): New.

	* 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.

From-SVN: r35985
parent 343b7260
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> 2000-08-25 Joseph S. Myers <jsm28@cam.ac.uk>
* c-common.c (time_char_table): Don't allow width and flags with * c-common.c (time_char_table): Don't allow width and flags with
......
...@@ -1033,6 +1033,11 @@ find_base_term (x) ...@@ -1033,6 +1033,11 @@ find_base_term (x)
cselib_val *val; cselib_val *val;
struct elt_loc_list *l; 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)) switch (GET_CODE (x))
{ {
case REG: case REG:
...@@ -1078,6 +1083,9 @@ find_base_term (x) ...@@ -1078,6 +1083,9 @@ find_base_term (x)
is a shift or multiply, then it must be the index register and the is a shift or multiply, then it must be the index register and the
other operand is the base register. */ 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 /* If either operand is known to be a pointer, then use it
to determine the base term. */ to determine the base term. */
if (REG_P (tmp1) && REGNO_POINTER_FLAG (REGNO (tmp1))) if (REG_P (tmp1) && REGNO_POINTER_FLAG (REGNO (tmp1)))
...@@ -1469,10 +1477,9 @@ memrefs_conflict_p (xsize, x, ysize, y, c) ...@@ -1469,10 +1477,9 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
canon_rtx (XEXP (y, 0)), c); canon_rtx (XEXP (y, 0)), c);
if (CONSTANT_P (y)) if (CONSTANT_P (y))
return (xsize < 0 || ysize < 0 return (xsize <= 0 || ysize <= 0
|| (rtx_equal_for_memref_p (x, y) || (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; return 1;
} }
...@@ -1574,14 +1581,14 @@ true_dependence (mem, mem_mode, x, varies) ...@@ -1574,14 +1581,14 @@ true_dependence (mem, mem_mode, x, varies)
if (DIFFERENT_ALIAS_SETS_P (x, mem)) if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0; return 0;
/* If X is an unchanging read, then it can't possibly conflict with any /* Unchanging memory can't conflict with non-unchanging memory.
non-unchanging store. It may conflict with an unchanging write though, A non-unchanging read can conflict with a non-unchanging write.
because there may be a single store to this address to initialize it. An unchanging read can conflict with an unchanging write since
Just fall through to the code below to resolve the case where we have there may be a single store to this address to initialize it.
both an unchanging read and an unchanging write. This won't handle all Just fall through to the code below to resolve potential conflicts.
cases optimally, but the possible performance loss should be This won't handle all cases optimally, but the possible performance
negligible. */ loss should be negligible. */
if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem)) if (RTX_UNCHANGING_P (x) != RTX_UNCHANGING_P (mem))
return 0; return 0;
if (mem_mode == VOIDmode) if (mem_mode == VOIDmode)
...@@ -1642,6 +1649,10 @@ write_dependence_p (mem, x, writep) ...@@ -1642,6 +1649,10 @@ write_dependence_p (mem, x, writep)
if (DIFFERENT_ALIAS_SETS_P (x, mem)) if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0; 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 /* 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 the store to X, because there is at most one store to MEM, and it must
have occurred somewhere before MEM. */ have occurred somewhere before MEM. */
......
...@@ -111,6 +111,7 @@ extern void ix86_split_ashrdi PARAMS ((rtx *, rtx)); ...@@ -111,6 +111,7 @@ extern void ix86_split_ashrdi PARAMS ((rtx *, rtx));
extern void ix86_split_lshrdi PARAMS ((rtx *, rtx)); extern void ix86_split_lshrdi PARAMS ((rtx *, rtx));
extern void ix86_expand_strlensi_unroll_1 PARAMS ((rtx, rtx, rtx)); extern void ix86_expand_strlensi_unroll_1 PARAMS ((rtx, rtx, rtx));
extern int ix86_address_cost PARAMS ((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 rtx assign_386_stack_local PARAMS ((enum machine_mode, int));
extern int ix86_attr_length_immediate_default PARAMS ((rtx, int)); extern int ix86_attr_length_immediate_default PARAMS ((rtx, int));
......
...@@ -2332,6 +2332,40 @@ ix86_address_cost (x) ...@@ -2332,6 +2332,40 @@ ix86_address_cost (x)
return cost; 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 /* Determine if a given CONST RTX is a valid memory displacement
in PIC mode. */ in PIC mode. */
......
...@@ -1659,6 +1659,17 @@ pop{l} %0" \ ...@@ -1659,6 +1659,17 @@ pop{l} %0" \
#endif #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 /* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid 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. 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, ...@@ -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 looking for one that is valid, and will reload one or both registers
only if neither labeling works. 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 @findex LEGITIMIZE_ADDRESS
@item LEGITIMIZE_ADDRESS (@var{x}, @var{oldx}, @var{mode}, @var{win}) @item LEGITIMIZE_ADDRESS (@var{x}, @var{oldx}, @var{mode}, @var{win})
A C compound statement that attempts to replace @var{x} with a valid 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