diff options
author | John Wehle <john@feith.com> | 2000-08-25 16:52:24 +0000 |
---|---|---|
committer | John Wehle <wehle@gcc.gnu.org> | 2000-08-25 16:52:24 +0000 |
commit | b949ea8b0f724013ec018b7af86ba134a229d723 (patch) | |
tree | 1f4cb865a07357d51f3f12cc3e78156fa5a0c581 | |
parent | 343b7260c6f4c4164fd65368a7d2391defcbd098 (diff) | |
download | gcc-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/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/alias.c | 33 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 34 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 11 | ||||
-rw-r--r-- | gcc/tm.texi | 11 |
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 |