aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wehle <john@feith.com>2000-08-25 16:52:24 +0000
committerJohn Wehle <wehle@gcc.gnu.org>2000-08-25 16:52:24 +0000
commitb949ea8b0f724013ec018b7af86ba134a229d723 (patch)
tree1f4cb865a07357d51f3f12cc3e78156fa5a0c581
parent343b7260c6f4c4164fd65368a7d2391defcbd098 (diff)
downloadgcc-b949ea8b0f724013ec018b7af86ba134a229d723.zip
gcc-b949ea8b0f724013ec018b7af86ba134a229d723.tar.gz
gcc-b949ea8b0f724013ec018b7af86ba134a229d723.tar.bz2
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
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/alias.c33
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c34
-rw-r--r--gcc/config/i386/i386.h11
-rw-r--r--gcc/tm.texi11
6 files changed, 94 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ae8f0ca..892c222 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+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
diff --git a/gcc/alias.c b/gcc/alias.c
index 5d96dad..cb5a636 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -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. */
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 18b258b..f5d075b 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -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));
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9fa6fab..aa9b497 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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. */
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 62f5fb0..d7ced866 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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.
diff --git a/gcc/tm.texi b/gcc/tm.texi
index 39e3df5..7006cbf 100644
--- a/gcc/tm.texi
+++ b/gcc/tm.texi
@@ -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