[PATCH, 4.8] Backport alias patches to 4.8 branch
Uros Bizjak
ubizjak@gmail.com
Thu Feb 19 16:39:00 GMT 2015
Hello!
I would like to port following patches to 4.8 branch:
2014-11-05 Uros Bizjak <ubizjak@gmail.com>
Backport from mainline
2015-01-22 Wei Mi <wmi@google.com>
PR rtl-optimization/64557
* dse.c (record_store): Call get_addr for mem_addr.
(check_mem_read_rtx): Likewise.
Backport from mainline
2014-10-20 Uros Bizjak <ubizjak@gmail.com>
* varasm.c (const_alias_set): Remove.
(init_varasm_once): Remove initialization of const_alias_set.
(build_constant_desc): Do not set alias set to const_alias_set.
Backport from mainline
2014-10-14 Uros Bizjak <ubizjak@gmail.com>
PR rtl-optimization/63475
* alias.c (true_dependence_1): Always use get_addr to extract
true address operands from x_addr and mem_addr. Use extracted
address operands to check for references with alignment ANDs.
Use extracted address operands with find_base_term and
base_alias_check. For noncanonicalized operands call canon_rtx with
extracted address operand.
(write_dependence_1): Ditto.
(may_alias_p): Ditto. Remove unused calls to canon_rtx.
Backport from mainline
2014-10-10 Uros Bizjak <ubizjak@gmail.com>
PR rtl-optimization/63483
* alias.c (true_dependence_1): Do not exit early for MEM_READONLY_P
references when alignment ANDs are involved.
(write_dependence_p): Ditto.
(may_alias_p): Ditto.
Backport from mainline
2013-03-26 Richard Biener <rguenther@suse.de>
* alias.c (find_base_term): Avoid redundant and not used recursion.
(base_alias_check): Get the initial base term from the caller.
(true_dependence_1): Compute and pass base terms to base_alias_check.
(write_dependence_p): Likewise.
(may_alias_p): Likewise.
Patches were bootstrapped and regression tested together with
bootstrap fixing patch [1] on alpha-linux-gnu and x86_64-linux-gnu
{,-m32}. These patches fix the same libgfortran failures as on
mainline and 4.9 (all these patches are already present or backported
to 4.9 branch).
The results for alpha-linux-gnu are at [2]
[1] https://gcc.gnu.org/ml/gcc-patches/2015-02/msg01127.html
[2] https://gcc.gnu.org/ml/gcc-testresults/2015-02/msg02244.html
OK for 4.8 branch?
Uros.
-------------- next part --------------
Index: alias.c
===================================================================
--- alias.c (revision 220763)
+++ alias.c (working copy)
@@ -148,7 +148,7 @@ typedef struct alias_set_entry_d *alias_set_entry;
static int rtx_equal_for_memref_p (const_rtx, const_rtx);
static int memrefs_conflict_p (int, rtx, int, rtx, HOST_WIDE_INT);
static void record_set (rtx, const_rtx, void *);
-static int base_alias_check (rtx, rtx, enum machine_mode,
+static int base_alias_check (rtx, rtx, rtx, rtx, enum machine_mode,
enum machine_mode);
static rtx find_base_value (rtx);
static int mems_in_disjoint_alias_sets_p (const_rtx, const_rtx);
@@ -1666,34 +1666,30 @@ find_base_term (rtx x)
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 prefer it
to determine the base term. */
if (REG_P (tmp1) && REG_POINTER (tmp1))
+ ;
+ else if (REG_P (tmp2) && REG_POINTER (tmp2))
{
- rtx base = find_base_term (tmp1);
- if (base)
- return base;
+ rtx tem = tmp1;
+ tmp1 = tmp2;
+ tmp2 = tem;
}
- if (REG_P (tmp2) && REG_POINTER (tmp2))
- {
- rtx base = find_base_term (tmp2);
- if (base)
- return base;
- }
-
- /* Neither operand was known to be a pointer. Go ahead and find the
- base term for both operands. */
- tmp1 = find_base_term (tmp1);
- tmp2 = find_base_term (tmp2);
-
- /* If either base term is named object or a special address
+ /* Go ahead and find the base term for both operands. If either base
+ term is from a pointer or is a named object or a special address
(like an argument or stack reference), then use it for the
base term. */
- if (tmp1 != 0 && known_base_value_p (tmp1))
+ tmp1 = find_base_term (tmp1);
+ if (tmp1 != NULL_RTX
+ && ((REG_P (tmp1) && REG_POINTER (tmp1))
+ || known_base_value_p (tmp1)))
return tmp1;
-
- if (tmp2 != 0 && known_base_value_p (tmp2))
+ tmp2 = find_base_term (tmp2);
+ if (tmp2 != NULL_RTX
+ && ((REG_P (tmp2) && REG_POINTER (tmp2))
+ || known_base_value_p (tmp2)))
return tmp2;
/* We could not determine which of the two operands was the
@@ -1730,12 +1726,9 @@ may_be_sp_based_p (rtx x)
objects, 1 if they might be pointers to the same object. */
static int
-base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
- enum machine_mode y_mode)
+base_alias_check (rtx x, rtx x_base, rtx y, rtx y_base,
+ enum machine_mode x_mode, enum machine_mode y_mode)
{
- rtx x_base = find_base_term (x);
- rtx y_base = find_base_term (y);
-
/* If the address itself has no known base see if a known equivalent
value has one. If either address still has no known base, nothing
is known about aliasing. */
@@ -2445,6 +2438,7 @@ static int
true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
const_rtx x, rtx x_addr, bool mem_canonicalized)
{
+ rtx true_mem_addr;
rtx base;
int ret;
@@ -2464,10 +2458,26 @@ true_dependence_1 (const_rtx mem, enum machine_mod
|| MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
return 1;
+ if (! x_addr)
+ x_addr = XEXP (x, 0);
+ x_addr = get_addr (x_addr);
+
+ if (! mem_addr)
+ {
+ mem_addr = XEXP (mem, 0);
+ if (mem_mode == VOIDmode)
+ mem_mode = GET_MODE (mem);
+ }
+ true_mem_addr = get_addr (mem_addr);
+
/* Read-only memory is by definition never modified, and therefore can't
- conflict with anything. We don't expect to find read-only set on MEM,
- but stupid user tricks can produce them, so don't die. */
- if (MEM_READONLY_P (x))
+ conflict with anything. However, don't assume anything when AND
+ addresses are involved and leave to the code below to determine
+ dependence. We don't expect to find read-only set on MEM, but
+ stupid user tricks can produce them, so don't die. */
+ if (MEM_READONLY_P (x)
+ && GET_CODE (x_addr) != AND
+ && GET_CODE (true_mem_addr) != AND)
return 0;
/* If we have MEMs referring to different address spaces (which can
@@ -2476,29 +2486,6 @@ true_dependence_1 (const_rtx mem, enum machine_mod
if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
return 1;
- if (! mem_addr)
- {
- mem_addr = XEXP (mem, 0);
- if (mem_mode == VOIDmode)
- mem_mode = GET_MODE (mem);
- }
-
- if (! x_addr)
- {
- x_addr = XEXP (x, 0);
- if (!((GET_CODE (x_addr) == VALUE
- && GET_CODE (mem_addr) != VALUE
- && reg_mentioned_p (x_addr, mem_addr))
- || (GET_CODE (x_addr) != VALUE
- && GET_CODE (mem_addr) == VALUE
- && reg_mentioned_p (mem_addr, x_addr))))
- {
- x_addr = get_addr (x_addr);
- if (! mem_canonicalized)
- mem_addr = get_addr (mem_addr);
- }
- }
-
base = find_base_term (x_addr);
if (base && (GET_CODE (base) == LABEL_REF
|| (GET_CODE (base) == SYMBOL_REF
@@ -2505,12 +2492,14 @@ true_dependence_1 (const_rtx mem, enum machine_mod
&& CONSTANT_POOL_ADDRESS_P (base))))
return 0;
- if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode))
+ rtx mem_base = find_base_term (true_mem_addr);
+ if (! base_alias_check (x_addr, base, true_mem_addr, mem_base,
+ GET_MODE (x), mem_mode))
return 0;
x_addr = canon_rtx (x_addr);
if (!mem_canonicalized)
- mem_addr = canon_rtx (mem_addr);
+ mem_addr = canon_rtx (true_mem_addr);
if ((ret = memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr,
SIZE_FOR_MODE (x), x_addr, 0)) != -1)
@@ -2563,6 +2552,7 @@ write_dependence_p (const_rtx mem,
bool mem_canonicalized, bool x_canonicalized, bool writep)
{
rtx mem_addr;
+ rtx true_mem_addr, true_x_addr;
rtx base;
int ret;
@@ -2583,8 +2573,20 @@ write_dependence_p (const_rtx mem,
|| MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
return 1;
- /* A read from read-only memory can't conflict with read-write memory. */
- if (!writep && MEM_READONLY_P (mem))
+ if (!x_addr)
+ x_addr = XEXP (x, 0);
+ true_x_addr = get_addr (x_addr);
+
+ mem_addr = XEXP (mem, 0);
+ true_mem_addr = get_addr (mem_addr);
+
+ /* A read from read-only memory can't conflict with read-write memory.
+ Don't assume anything when AND addresses are involved and leave to
+ the code below to determine dependence. */
+ if (!writep
+ && MEM_READONLY_P (mem)
+ && GET_CODE (true_x_addr) != AND
+ && GET_CODE (true_mem_addr) != AND)
return 0;
/* If we have MEMs referring to different address spaces (which can
@@ -2593,43 +2595,26 @@ write_dependence_p (const_rtx mem,
if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
return 1;
- mem_addr = XEXP (mem, 0);
- if (!x_addr)
- {
- x_addr = XEXP (x, 0);
- if (!((GET_CODE (x_addr) == VALUE
- && GET_CODE (mem_addr) != VALUE
- && reg_mentioned_p (x_addr, mem_addr))
- || (GET_CODE (x_addr) != VALUE
- && GET_CODE (mem_addr) == VALUE
- && reg_mentioned_p (mem_addr, x_addr))))
- {
- x_addr = get_addr (x_addr);
- if (!mem_canonicalized)
- mem_addr = get_addr (mem_addr);
- }
- }
+ base = find_base_term (true_mem_addr);
+ if (! writep
+ && base
+ && (GET_CODE (base) == LABEL_REF
+ || (GET_CODE (base) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (base))))
+ return 0;
- if (! writep)
- {
- base = find_base_term (mem_addr);
- if (base && (GET_CODE (base) == LABEL_REF
- || (GET_CODE (base) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (base))))
- return 0;
- }
-
- if (! base_alias_check (x_addr, mem_addr, GET_MODE (x),
- GET_MODE (mem)))
+ rtx x_base = find_base_term (true_x_addr);
+ if (! base_alias_check (true_x_addr, x_base, true_mem_addr, base,
+ GET_MODE (x), GET_MODE (mem)))
return 0;
if (!x_canonicalized)
{
- x_addr = canon_rtx (x_addr);
+ x_addr = canon_rtx (true_x_addr);
x_mode = GET_MODE (x);
}
if (!mem_canonicalized)
- mem_addr = canon_rtx (mem_addr);
+ mem_addr = canon_rtx (true_mem_addr);
if ((ret = memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr,
GET_MODE_SIZE (x_mode), x_addr, 0)) != -1)
@@ -2697,10 +2682,20 @@ may_alias_p (const_rtx mem, const_rtx x)
|| MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
return 1;
+ x_addr = XEXP (x, 0);
+ x_addr = get_addr (x_addr);
+
+ mem_addr = XEXP (mem, 0);
+ mem_addr = get_addr (mem_addr);
+
/* Read-only memory is by definition never modified, and therefore can't
- conflict with anything. We don't expect to find read-only set on MEM,
- but stupid user tricks can produce them, so don't die. */
- if (MEM_READONLY_P (x))
+ conflict with anything. However, don't assume anything when AND
+ addresses are involved and leave to the code below to determine
+ dependence. We don't expect to find read-only set on MEM, but
+ stupid user tricks can produce them, so don't die. */
+ if (MEM_READONLY_P (x)
+ && GET_CODE (x_addr) != AND
+ && GET_CODE (mem_addr) != AND)
return 0;
/* If we have MEMs referring to different address spaces (which can
@@ -2709,25 +2704,12 @@ may_alias_p (const_rtx mem, const_rtx x)
if (MEM_ADDR_SPACE (mem) != MEM_ADDR_SPACE (x))
return 1;
- x_addr = XEXP (x, 0);
- mem_addr = XEXP (mem, 0);
- if (!((GET_CODE (x_addr) == VALUE
- && GET_CODE (mem_addr) != VALUE
- && reg_mentioned_p (x_addr, mem_addr))
- || (GET_CODE (x_addr) != VALUE
- && GET_CODE (mem_addr) == VALUE
- && reg_mentioned_p (mem_addr, x_addr))))
- {
- x_addr = get_addr (x_addr);
- mem_addr = get_addr (mem_addr);
- }
-
- if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), GET_MODE (mem_addr)))
+ rtx x_base = find_base_term (x_addr);
+ rtx mem_base = find_base_term (mem_addr);
+ if (! base_alias_check (x_addr, x_base, mem_addr, mem_base,
+ GET_MODE (x), GET_MODE (mem_addr)))
return 0;
- x_addr = canon_rtx (x_addr);
- mem_addr = canon_rtx (mem_addr);
-
if (nonoverlapping_memrefs_p (mem, x, true))
return 0;
Index: varasm.c
===================================================================
--- varasm.c (revision 220763)
+++ varasm.c (working copy)
@@ -91,11 +91,6 @@ tree last_assemble_variable_decl;
bool first_function_block_is_cold;
-/* We give all constants their own alias set. Perhaps redundant with
- MEM_READONLY_P, but pre-dates it. */
-
-static alias_set_type const_alias_set;
-
/* Whether we saw any functions with no_split_stack. */
static bool saw_no_split_stack;
@@ -3139,7 +3134,6 @@ build_constant_desc (tree exp)
rtl = gen_const_mem (TYPE_MODE (TREE_TYPE (exp)), symbol);
set_mem_attributes (rtl, exp, 1);
set_mem_alias_set (rtl, 0);
- set_mem_alias_set (rtl, const_alias_set);
/* We cannot share RTX'es in pool entries.
Mark this piece of RTL as required for unsharing. */
@@ -5865,7 +5859,6 @@ init_varasm_once (void)
const_desc_htab = htab_create_ggc (1009, const_desc_hash,
const_desc_eq, NULL);
- const_alias_set = new_alias_set ();
shared_constant_pool = create_constant_pool ();
#ifdef TEXT_SECTION_ASM_OP
Index: dse.c
===================================================================
--- dse.c (revision 220763)
+++ dse.c (working copy)
@@ -1594,6 +1594,10 @@ record_store (rtx body, bb_info_t bb_info)
= rtx_group_vec[group_id];
mem_addr = group->canon_base_addr;
}
+ /* get_addr can only handle VALUE but cannot handle expr like:
+ VALUE + OFFSET, so call get_addr to get original addr for
+ mem_addr before plus_constant. */
+ mem_addr = get_addr (mem_addr);
if (offset)
mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset);
}
@@ -2211,6 +2215,10 @@ check_mem_read_rtx (rtx *loc, void *data)
= rtx_group_vec[group_id];
mem_addr = group->canon_base_addr;
}
+ /* get_addr can only handle VALUE but cannot handle expr like:
+ VALUE + OFFSET, so call get_addr to get original addr for
+ mem_addr before plus_constant. */
+ mem_addr = get_addr (mem_addr);
if (offset)
mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset);
}
More information about the Gcc-patches
mailing list