diff options
Diffstat (limited to 'gcc/alias.c')
-rw-r--r-- | gcc/alias.c | 87 |
1 files changed, 86 insertions, 1 deletions
diff --git a/gcc/alias.c b/gcc/alias.c index d670a7db19e..99d9c5d458a 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -112,6 +112,11 @@ static bool nonoverlapping_component_refs_p (tree, tree); static tree decl_for_component_ref (tree); static rtx adjust_offset_for_component_ref (tree, rtx); static int nonoverlapping_memrefs_p (rtx, rtx); + +/* APPLE LOCAL */ +static int overlapping_memrefs_p (rtx, rtx); +/* APPLE LOCAL end */ + static int write_dependence_p (rtx, rtx, int, int); static int nonlocal_mentioned_p_1 (rtx *, void *); @@ -2070,6 +2075,65 @@ nonoverlapping_memrefs_p (rtx x, rtx y) return sizex >= 0 && offsety >= offsetx + sizex; } +/* APPLE LOCAL aliasing improvement */ +/* Helper for the following. Return 1 only if we're sure of overlap. */ + +static int +overlapping_trees_p (tree exprx, tree expry) +{ + /* If no info about either one, can't tell. */ + if (exprx == 0 || expry == 0) + return 0; + + /* Top level code must match. */ + if (TREE_CODE (exprx) != TREE_CODE (expry)) + return 0; + + /* Components. */ + if (TREE_CODE (exprx) == COMPONENT_REF) + { + /* They must refer to the same field... */ + if (TREE_OPERAND (exprx, 1) != TREE_OPERAND (expry, 1)) + return 0; + /* ...of the same object. (The object may be null, which + will compare as not overlapping.) */ + return overlapping_trees_p (TREE_OPERAND (exprx, 0), + TREE_OPERAND (expry, 0)); + } + + /* Pointers. */ + if (TREE_CODE (exprx) == INDIRECT_REF) + return overlapping_trees_p (TREE_OPERAND (exprx, 0), + TREE_OPERAND (expry, 0)); + + if (TREE_CODE (exprx) == VAR_DECL + || TREE_CODE (exprx) == PARM_DECL + || TREE_CODE (exprx) == CONST_DECL + || TREE_CODE (exprx) == FUNCTION_DECL) + return exprx == expry; + + return 0; +} + +/* Return 1 if memrefs definitely overlap, 0 otherwise. */ + + +static int +overlapping_memrefs_p (rtx x, rtx y) +{ + tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y); + rtx offsetx = MEM_OFFSET (x), offsety = MEM_OFFSET (y); + + /* See if offsets collide. Known but different offsets do not + overlap. Unknown offsets will if the underlying object is the same. */ + if (offsetx != 0 && offsety != 0 && !rtx_equal_p (offsetx, offsety)) + return 0; + + return overlapping_trees_p (exprx, expry); +} +/* APPLE LOCAL end aliasing improvement */ + + /* True dependence: X is read after store in MEM takes place. */ int @@ -2120,6 +2184,10 @@ true_dependence (rtx mem, enum machine_mode mem_mode, rtx x, && CONSTANT_POOL_ADDRESS_P (base)))) return 0; + /* APPLE LOCAL */ + if (overlapping_memrefs_p (mem, x)) + return 1; + if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode)) return 0; @@ -2187,6 +2255,10 @@ canon_true_dependence (rtx mem, enum machine_mode mem_mode, rtx mem_addr, x_addr = get_addr (XEXP (x, 0)); + /* APPLE LOCAL */ + if (overlapping_memrefs_p (mem, x)) + return 1; + if (! base_alias_check (x_addr, mem_addr, GET_MODE (x), mem_mode)) return 0; @@ -2233,6 +2305,19 @@ write_dependence_p (rtx mem, rtx x, int writep, int constp) if (GET_MODE (mem) == BLKmode && GET_CODE (XEXP (mem, 0)) == SCRATCH) return 1; + /* APPLE LOCAL begin make SPEC gcc work with strict aliasing */ + x_addr = get_addr (XEXP (x, 0)); + mem_addr = get_addr (XEXP (mem, 0)); + + /* If two addresses are "the same" they conflict, even if type + checking says they don't. This is a bit too conservative + since there's no guarantee identical registers will have the + same values in both addresses. This is required to build + the (nonstandard) version of gcc found in SPEC. */ + if (rtx_equal_p (x_addr, mem_addr)) + return 1; + /* APPLE LOCAL end make SPEC gcc work with strict aliasing */ + if (DIFFERENT_ALIAS_SETS_P (x, mem)) return 0; @@ -2752,7 +2837,7 @@ init_alias_analysis (void) new_reg_base_value = xmalloc (maxreg * sizeof (rtx)); reg_seen = xmalloc (maxreg); - if (! reload_completed && flag_old_unroll_loops) + if (! reload_completed && flag_unroll_loops) { /* ??? Why are we realloc'ing if we're just going to zero it? */ alias_invariant = xrealloc (alias_invariant, |