Mercurial > hg > CbC > CbC_gcc
diff gcc/alias.c @ 132:d34655255c78
update gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 10:21:07 +0900 |
parents | 84e7813d76e9 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/alias.c Thu Oct 25 08:08:40 2018 +0900 +++ b/gcc/alias.c Thu Oct 25 10:21:07 2018 +0900 @@ -1,5 +1,5 @@ /* Alias analysis for GNU C - Copyright (C) 1997-2017 Free Software Foundation, Inc. + Copyright (C) 1997-2018 Free Software Foundation, Inc. Contributed by John Carr (jfc@mit.edu). This file is part of GCC. @@ -148,7 +148,6 @@ }; 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, rtx, rtx, machine_mode, machine_mode); @@ -330,10 +329,10 @@ /* If MEM_OFFSET/MEM_SIZE get us outside of ref->offset/ref->max_size drop ref->ref. */ - if (MEM_OFFSET (mem) < 0 - || (ref->max_size != -1 - && ((MEM_OFFSET (mem) + MEM_SIZE (mem)) * BITS_PER_UNIT - > ref->max_size))) + if (maybe_lt (MEM_OFFSET (mem), 0) + || (ref->max_size_known_p () + && maybe_gt ((MEM_OFFSET (mem) + MEM_SIZE (mem)) * BITS_PER_UNIT, + ref->max_size))) ref->ref = NULL_TREE; /* Refine size and offset we got from analyzing MEM_EXPR by using @@ -344,19 +343,18 @@ /* The MEM may extend into adjacent fields, so adjust max_size if necessary. */ - if (ref->max_size != -1 - && ref->size > ref->max_size) - ref->max_size = ref->size; - - /* If MEM_OFFSET and MEM_SIZE get us outside of the base object of + if (ref->max_size_known_p ()) + ref->max_size = upper_bound (ref->max_size, ref->size); + + /* If MEM_OFFSET and MEM_SIZE might get us outside of the base object of the MEM_EXPR punt. This happens for STRICT_ALIGNMENT targets a lot. */ if (MEM_EXPR (mem) != get_spill_slot_decl (false) - && (ref->offset < 0 + && (maybe_lt (ref->offset, 0) || (DECL_P (ref->base) && (DECL_SIZE (ref->base) == NULL_TREE - || TREE_CODE (DECL_SIZE (ref->base)) != INTEGER_CST - || wi::ltu_p (wi::to_offset (DECL_SIZE (ref->base)), - ref->offset + ref->size))))) + || !poly_int_tree_p (DECL_SIZE (ref->base)) + || maybe_lt (wi::to_poly_offset (DECL_SIZE (ref->base)), + ref->offset + ref->size))))) return false; return true; @@ -1349,6 +1347,7 @@ find_base_value (rtx src) { unsigned int regno; + scalar_int_mode int_mode; #if defined (FIND_BASE_TERM) /* Try machine-dependent ways to find the base term. */ @@ -1475,7 +1474,8 @@ address modes depending on the address space. */ if (!target_default_pointer_address_modes_p ()) break; - if (GET_MODE_SIZE (GET_MODE (src)) < GET_MODE_SIZE (Pmode)) + if (!is_a <scalar_int_mode> (GET_MODE (src), &int_mode) + || GET_MODE_PRECISION (int_mode) < GET_MODE_PRECISION (Pmode)) break; /* Fall through. */ case HIGH: @@ -1554,6 +1554,17 @@ new_reg_base_value[regno] = 0; return; } + /* A CLOBBER_HIGH only wipes out the old value if the mode of the old + value is greater than that of the clobber. */ + else if (GET_CODE (set) == CLOBBER_HIGH) + { + if (new_reg_base_value[regno] != 0 + && reg_is_clobbered_by_clobber_high ( + regno, GET_MODE (new_reg_base_value[regno]), XEXP (set, 0))) + new_reg_base_value[regno] = 0; + return; + } + src = SET_SRC (set); } else @@ -1832,6 +1843,11 @@ return 0; break; + case 'p': + if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y))) + return 0; + break; + case 'E': /* Two vectors must have the same length. */ if (XVECLEN (x, i) != XVECLEN (y, i)) @@ -1871,11 +1887,13 @@ } static rtx -find_base_term (rtx x) +find_base_term (rtx x, vec<std::pair<cselib_val *, + struct elt_loc_list *> > &visited_vals) { cselib_val *val; struct elt_loc_list *l, *f; rtx ret; + scalar_int_mode int_mode; #if defined (FIND_BASE_TERM) /* Try machine-dependent ways to find the base term. */ @@ -1893,7 +1911,8 @@ address modes depending on the address space. */ if (!target_default_pointer_address_modes_p ()) return 0; - if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (Pmode)) + if (!is_a <scalar_int_mode> (GET_MODE (x), &int_mode) + || GET_MODE_PRECISION (int_mode) < GET_MODE_PRECISION (Pmode)) return 0; /* Fall through. */ case HIGH: @@ -1903,7 +1922,7 @@ case POST_DEC: case PRE_MODIFY: case POST_MODIFY: - return find_base_term (XEXP (x, 0)); + return find_base_term (XEXP (x, 0), visited_vals); case ZERO_EXTEND: case SIGN_EXTEND: /* Used for Alpha/NT pointers */ @@ -1914,7 +1933,7 @@ return 0; { - rtx temp = find_base_term (XEXP (x, 0)); + rtx temp = find_base_term (XEXP (x, 0), visited_vals); if (temp != 0 && CONSTANT_P (temp)) temp = convert_memory_address (Pmode, temp); @@ -1933,7 +1952,9 @@ return static_reg_base_value[STACK_POINTER_REGNUM]; f = val->locs; - /* Temporarily reset val->locs to avoid infinite recursion. */ + /* Reset val->locs to avoid infinite recursion. */ + if (f) + visited_vals.safe_push (std::make_pair (val, f)); val->locs = NULL; for (l = f; l; l = l->next) @@ -1942,16 +1963,15 @@ && !CSELIB_VAL_PTR (l->loc)->locs->next && CSELIB_VAL_PTR (l->loc)->locs->loc == x) continue; - else if ((ret = find_base_term (l->loc)) != 0) + else if ((ret = find_base_term (l->loc, visited_vals)) != 0) break; - val->locs = f; return ret; case LO_SUM: /* The standard form is (lo_sum reg sym) so look only at the second operand. */ - return find_base_term (XEXP (x, 1)); + return find_base_term (XEXP (x, 1), visited_vals); case CONST: x = XEXP (x, 0); @@ -1977,7 +1997,7 @@ other operand is the base register. */ if (tmp1 == pic_offset_table_rtx && CONSTANT_P (tmp2)) - return find_base_term (tmp2); + return find_base_term (tmp2, visited_vals); /* If either operand is known to be a pointer, then prefer it to determine the base term. */ @@ -1994,12 +2014,12 @@ 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. */ - rtx base = find_base_term (tmp1); + rtx base = find_base_term (tmp1, visited_vals); if (base != NULL_RTX && ((REG_P (tmp1) && REG_POINTER (tmp1)) || known_base_value_p (base))) return base; - base = find_base_term (tmp2); + base = find_base_term (tmp2, visited_vals); if (base != NULL_RTX && ((REG_P (tmp2) && REG_POINTER (tmp2)) || known_base_value_p (base))) @@ -2013,7 +2033,7 @@ case AND: if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0) - return find_base_term (XEXP (x, 0)); + return find_base_term (XEXP (x, 0), visited_vals); return 0; case SYMBOL_REF: @@ -2025,6 +2045,19 @@ } } +/* Wrapper around the worker above which removes locs from visited VALUEs + to avoid visiting them multiple times. We unwind that changes here. */ + +static rtx +find_base_term (rtx x) +{ + auto_vec<std::pair<cselib_val *, struct elt_loc_list *>, 32> visited_vals; + rtx res = find_base_term (x, visited_vals); + for (unsigned i = 0; i < visited_vals.length (); ++i) + visited_vals[i].first->locs = visited_vals[i].second; + return res; +} + /* Return true if accesses to address X may alias accesses based on the stack pointer. */ @@ -2240,9 +2273,10 @@ rtx op0 = get_addr (XEXP (x, 0)); if (op0 != XEXP (x, 0)) { + poly_int64 c; if (GET_CODE (x) == PLUS - && GET_CODE (XEXP (x, 1)) == CONST_INT) - return plus_constant (GET_MODE (x), op0, INTVAL (XEXP (x, 1))); + && poly_int_rtx_p (XEXP (x, 1), &c)) + return plus_constant (GET_MODE (x), op0, c); return simplify_gen_binary (GET_CODE (x), GET_MODE (x), op0, XEXP (x, 1)); } @@ -2289,9 +2323,9 @@ is not modified by the memory reference then ADDR is returned. */ static rtx -addr_side_effect_eval (rtx addr, int size, int n_refs) +addr_side_effect_eval (rtx addr, poly_int64 size, int n_refs) { - int offset = 0; + poly_int64 offset = 0; switch (GET_CODE (addr)) { @@ -2312,11 +2346,7 @@ return addr; } - if (offset) - addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0), - gen_int_mode (offset, GET_MODE (addr))); - else - addr = XEXP (addr, 0); + addr = plus_constant (GET_MODE (addr), XEXP (addr, 0), offset); addr = canon_rtx (addr); return addr; @@ -2328,12 +2358,15 @@ absolute value of the sizes as the actual sizes. */ static inline bool -offset_overlap_p (HOST_WIDE_INT c, int xsize, int ysize) +offset_overlap_p (poly_int64 c, poly_int64 xsize, poly_int64 ysize) { - return (xsize == 0 || ysize == 0 - || (c >= 0 - ? (abs (xsize) > c) - : (abs (ysize) > -c))); + if (known_eq (xsize, 0) || known_eq (ysize, 0)) + return true; + + if (maybe_ge (c, 0)) + return maybe_gt (maybe_lt (xsize, 0) ? -xsize : xsize, c); + else + return maybe_gt (maybe_lt (ysize, 0) ? -ysize : ysize, -c); } /* Return one if X and Y (memory addresses) reference the @@ -2363,7 +2396,8 @@ If that is fixed the TBAA hack for union type-punning can be removed. */ static int -memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) +memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, + poly_int64 c) { if (GET_CODE (x) == VALUE) { @@ -2408,13 +2442,13 @@ else if (GET_CODE (x) == LO_SUM) x = XEXP (x, 1); else - x = addr_side_effect_eval (x, abs (xsize), 0); + x = addr_side_effect_eval (x, maybe_lt (xsize, 0) ? -xsize : xsize, 0); if (GET_CODE (y) == HIGH) y = XEXP (y, 0); else if (GET_CODE (y) == LO_SUM) y = XEXP (y, 1); else - y = addr_side_effect_eval (y, abs (ysize), 0); + y = addr_side_effect_eval (y, maybe_lt (ysize, 0) ? -ysize : ysize, 0); if (GET_CODE (x) == SYMBOL_REF && GET_CODE (y) == SYMBOL_REF) { @@ -2427,7 +2461,7 @@ through alignment adjustments (i.e., that have negative sizes), because we can't know how far they are from each other. */ - if (xsize < 0 || ysize < 0) + if (maybe_lt (xsize, 0) || maybe_lt (ysize, 0)) return -1; /* If decls are different or we know by offsets that there is no overlap, we win. */ @@ -2458,6 +2492,7 @@ else if (x1 == y) return memrefs_conflict_p (xsize, x0, ysize, const0_rtx, c); + poly_int64 cx1, cy1; if (GET_CODE (y) == PLUS) { /* The fact that Y is canonicalized means that this @@ -2474,22 +2509,21 @@ return memrefs_conflict_p (xsize, x0, ysize, y0, c); if (rtx_equal_for_memref_p (x0, y0)) return memrefs_conflict_p (xsize, x1, ysize, y1, c); - if (CONST_INT_P (x1)) + if (poly_int_rtx_p (x1, &cx1)) { - if (CONST_INT_P (y1)) + if (poly_int_rtx_p (y1, &cy1)) return memrefs_conflict_p (xsize, x0, ysize, y0, - c - INTVAL (x1) + INTVAL (y1)); + c - cx1 + cy1); else - return memrefs_conflict_p (xsize, x0, ysize, y, - c - INTVAL (x1)); + return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1); } - else if (CONST_INT_P (y1)) - return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); + else if (poly_int_rtx_p (y1, &cy1)) + return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1); return -1; } - else if (CONST_INT_P (x1)) - return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); + else if (poly_int_rtx_p (x1, &cx1)) + return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1); } else if (GET_CODE (y) == PLUS) { @@ -2503,8 +2537,9 @@ if (x == y1) return memrefs_conflict_p (xsize, const0_rtx, ysize, y0, c); - if (CONST_INT_P (y1)) - return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); + poly_int64 cy1; + if (poly_int_rtx_p (y1, &cy1)) + return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1); else return -1; } @@ -2528,11 +2563,12 @@ return offset_overlap_p (c, xsize, ysize); /* Can't properly adjust our sizes. */ - if (!CONST_INT_P (x1)) + poly_int64 c1; + if (!poly_int_rtx_p (x1, &c1) + || !can_div_trunc_p (xsize, c1, &xsize) + || !can_div_trunc_p (ysize, c1, &ysize) + || !can_div_trunc_p (c, c1, &c)) return -1; - xsize /= INTVAL (x1); - ysize /= INTVAL (x1); - c /= INTVAL (x1); return memrefs_conflict_p (xsize, x0, ysize, y0, c); } @@ -2553,9 +2589,9 @@ unsigned HOST_WIDE_INT uc = sc; if (sc < 0 && pow2_or_zerop (-uc)) { - if (xsize > 0) + if (maybe_gt (xsize, 0)) xsize = -xsize; - if (xsize) + if (maybe_ne (xsize, 0)) xsize += sc + 1; c -= sc + 1; return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), @@ -2568,9 +2604,9 @@ unsigned HOST_WIDE_INT uc = sc; if (sc < 0 && pow2_or_zerop (-uc)) { - if (ysize > 0) + if (maybe_gt (ysize, 0)) ysize = -ysize; - if (ysize) + if (maybe_ne (ysize, 0)) ysize += sc + 1; c += sc + 1; return memrefs_conflict_p (xsize, x, @@ -2580,9 +2616,10 @@ if (CONSTANT_P (x)) { - if (CONST_INT_P (x) && CONST_INT_P (y)) + poly_int64 cx, cy; + if (poly_int_rtx_p (x, &cx) && poly_int_rtx_p (y, &cy)) { - c += (INTVAL (y) - INTVAL (x)); + c += cy - cx; return offset_overlap_p (c, xsize, ysize); } @@ -2604,7 +2641,9 @@ sizes), because we can't know how far they are from each other. */ if (CONSTANT_P (y)) - return (xsize < 0 || ysize < 0 || offset_overlap_p (c, xsize, ysize)); + return (maybe_lt (xsize, 0) + || maybe_lt (ysize, 0) + || offset_overlap_p (c, xsize, ysize)); return -1; } @@ -2664,7 +2703,7 @@ static void adjust_offset_for_component_ref (tree x, bool *known_p, - HOST_WIDE_INT *offset) + poly_int64 *offset) { if (!*known_p) return; @@ -2672,22 +2711,22 @@ { tree xoffset = component_ref_field_offset (x); tree field = TREE_OPERAND (x, 1); - if (TREE_CODE (xoffset) != INTEGER_CST) + if (!poly_int_tree_p (xoffset)) { *known_p = false; return; } - offset_int woffset - = (wi::to_offset (xoffset) + poly_offset_int woffset + = (wi::to_poly_offset (xoffset) + (wi::to_offset (DECL_FIELD_BIT_OFFSET (field)) - >> LOG2_BITS_PER_UNIT)); - if (!wi::fits_uhwi_p (woffset)) + >> LOG2_BITS_PER_UNIT) + + *offset); + if (!woffset.to_shwi (offset)) { *known_p = false; return; } - *offset += woffset.to_uhwi (); x = TREE_OPERAND (x, 0); } @@ -2705,8 +2744,8 @@ rtx rtlx, rtly; rtx basex, basey; bool moffsetx_known_p, moffsety_known_p; - HOST_WIDE_INT moffsetx = 0, moffsety = 0; - HOST_WIDE_INT offsetx = 0, offsety = 0, sizex, sizey; + poly_int64 moffsetx = 0, moffsety = 0; + poly_int64 offsetx = 0, offsety = 0, sizex, sizey; /* Unless both have exprs, we can't tell anything. */ if (exprx == 0 || expry == 0) @@ -2808,12 +2847,10 @@ we can avoid overlap is if we can deduce that they are nonoverlapping pieces of that decl, which is very rare. */ basex = MEM_P (rtlx) ? XEXP (rtlx, 0) : rtlx; - if (GET_CODE (basex) == PLUS && CONST_INT_P (XEXP (basex, 1))) - offsetx = INTVAL (XEXP (basex, 1)), basex = XEXP (basex, 0); + basex = strip_offset_and_add (basex, &offsetx); basey = MEM_P (rtly) ? XEXP (rtly, 0) : rtly; - if (GET_CODE (basey) == PLUS && CONST_INT_P (XEXP (basey, 1))) - offsety = INTVAL (XEXP (basey, 1)), basey = XEXP (basey, 0); + basey = strip_offset_and_add (basey, &offsety); /* If the bases are different, we know they do not overlap if both are constants or if one is a constant and the other a pointer into the @@ -2834,10 +2871,10 @@ declarations are necessarily different (i.e. compare_base_decls (exprx, expry) == -1) */ - sizex = (!MEM_P (rtlx) ? (int) GET_MODE_SIZE (GET_MODE (rtlx)) + sizex = (!MEM_P (rtlx) ? poly_int64 (GET_MODE_SIZE (GET_MODE (rtlx))) : MEM_SIZE_KNOWN_P (rtlx) ? MEM_SIZE (rtlx) : -1); - sizey = (!MEM_P (rtly) ? (int) GET_MODE_SIZE (GET_MODE (rtly)) + sizey = (!MEM_P (rtly) ? poly_int64 (GET_MODE_SIZE (GET_MODE (rtly))) : MEM_SIZE_KNOWN_P (rtly) ? MEM_SIZE (rtly) : -1); @@ -2856,16 +2893,7 @@ if (MEM_SIZE_KNOWN_P (y) && moffsety_known_p) sizey = MEM_SIZE (y); - /* Put the values of the memref with the lower offset in X's values. */ - if (offsetx > offsety) - { - std::swap (offsetx, offsety); - std::swap (sizex, sizey); - } - - /* If we don't know the size of the lower-offset value, we can't tell - if they conflict. Otherwise, we do the test. */ - return sizex >= 0 && offsety >= offsetx + sizex; + return !ranges_maybe_overlap_p (offsetx, sizex, offsety, sizey); } /* Helper for true_dependence and canon_true_dependence. @@ -2999,7 +3027,8 @@ int ret; gcc_checking_assert (x_canonicalized - ? (x_addr != NULL_RTX && x_mode != VOIDmode) + ? (x_addr != NULL_RTX + && (x_mode != VOIDmode || GET_MODE (x) == VOIDmode)) : (x_addr == NULL_RTX && x_mode == VOIDmode)); if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) @@ -3191,12 +3220,21 @@ && targetm.hard_regno_mode_ok (i, Pmode)) static_reg_base_value[i] = arg_base_value; + /* RTL code is required to be consistent about whether it uses the + stack pointer, the frame pointer or the argument pointer to + access a given area of the frame. We can therefore use the + base address to distinguish between the different areas. */ static_reg_base_value[STACK_POINTER_REGNUM] = unique_base_value (UNIQUE_BASE_VALUE_SP); static_reg_base_value[ARG_POINTER_REGNUM] = unique_base_value (UNIQUE_BASE_VALUE_ARGP); static_reg_base_value[FRAME_POINTER_REGNUM] = unique_base_value (UNIQUE_BASE_VALUE_FP); + + /* The above rules extend post-reload, with eliminations applying + consistently to each of the three pointers. Cope with cases in + which the frame pointer is eliminated to the hard frame pointer + rather than the stack pointer. */ if (!HARD_FRAME_POINTER_IS_FRAME_POINTER) static_reg_base_value[HARD_FRAME_POINTER_REGNUM] = unique_base_value (UNIQUE_BASE_VALUE_HFP); @@ -3232,15 +3270,6 @@ return memory_modified; } -/* Return TRUE if the destination of a set is rtx identical to - ITEM. */ -static inline bool -set_dest_equal_p (const_rtx set, const_rtx item) -{ - rtx dest = SET_DEST (set); - return rtx_equal_p (dest, item); -} - /* Initialize the aliasing machinery. Initialize the REG_KNOWN_VALUE array. */ @@ -3329,7 +3358,14 @@ /* Initialize the alias information for this pass. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - if (static_reg_base_value[i]) + if (static_reg_base_value[i] + /* Don't treat the hard frame pointer as special if we + eliminated the frame pointer to the stack pointer instead. */ + && !(i == HARD_FRAME_POINTER_REGNUM + && reload_completed + && !frame_pointer_needed + && targetm.can_eliminate (FRAME_POINTER_REGNUM, + STACK_POINTER_REGNUM))) { new_reg_base_value[i] = static_reg_base_value[i]; bitmap_set_bit (reg_seen, i); @@ -3375,6 +3411,7 @@ && DF_REG_DEF_COUNT (regno) != 1) note = NULL_RTX; + poly_int64 offset; if (note != NULL_RTX && GET_CODE (XEXP (note, 0)) != EXPR_LIST && ! rtx_varies_p (XEXP (note, 0), 1) @@ -3389,10 +3426,9 @@ && GET_CODE (src) == PLUS && REG_P (XEXP (src, 0)) && (t = get_reg_known_value (REGNO (XEXP (src, 0)))) - && CONST_INT_P (XEXP (src, 1))) + && poly_int_rtx_p (XEXP (src, 1), &offset)) { - t = plus_constant (GET_MODE (src), t, - INTVAL (XEXP (src, 1))); + t = plus_constant (GET_MODE (src), t, offset); set_reg_known_value (regno, t); set_reg_known_equiv_p (regno, false); }