diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 40 | ||||
-rw-r--r-- | gcc/tree.h | 11 |
3 files changed, 38 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 70e8c1a..3aca9c5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -2,6 +2,15 @@ Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> + * tree.h (get_inner_reference): Add a version that returns the + offset and size as poly_int64_pods rather than HOST_WIDE_INTs. + * cfgexpand.c (expand_debug_expr): Track polynomial offsets. Simply + the case in which bitpos is not associated with the first byte. + +2017-12-20 Richard Sandiford <richard.sandiford@linaro.org> + Alan Hayward <alan.hayward@arm.com> + David Sherwood <david.sherwood@arm.com> + * tree-affine.h (get_inner_reference_aff): Return the size as a poly_widest_int. * tree-affine.c (get_inner_reference_aff): Likewise. diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 324e097..d509326 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -4470,7 +4470,7 @@ expand_debug_expr (tree exp) case VIEW_CONVERT_EXPR: { machine_mode mode1; - HOST_WIDE_INT bitsize, bitpos; + poly_int64 bitsize, bitpos; tree offset; int reversep, volatilep = 0; tree tem @@ -4478,7 +4478,7 @@ expand_debug_expr (tree exp) &unsignedp, &reversep, &volatilep); rtx orig_op0; - if (bitsize == 0) + if (known_eq (bitsize, 0)) return NULL; orig_op0 = op0 = expand_debug_expr (tem); @@ -4521,19 +4521,14 @@ expand_debug_expr (tree exp) if (mode1 == VOIDmode) /* Bitfield. */ mode1 = smallest_int_mode_for_size (bitsize); - if (bitpos >= BITS_PER_UNIT) + poly_int64 bytepos = bits_to_bytes_round_down (bitpos); + if (maybe_ne (bytepos, 0)) { - op0 = adjust_address_nv (op0, mode1, bitpos / BITS_PER_UNIT); - bitpos %= BITS_PER_UNIT; + op0 = adjust_address_nv (op0, mode1, bytepos); + bitpos = num_trailing_bits (bitpos); } - else if (bitpos < 0) - { - HOST_WIDE_INT units - = (-bitpos + BITS_PER_UNIT - 1) / BITS_PER_UNIT; - op0 = adjust_address_nv (op0, mode1, -units); - bitpos += units * BITS_PER_UNIT; - } - else if (bitpos == 0 && bitsize == GET_MODE_BITSIZE (mode)) + else if (known_eq (bitpos, 0) + && known_eq (bitsize, GET_MODE_BITSIZE (mode))) op0 = adjust_address_nv (op0, mode, 0); else if (GET_MODE (op0) != mode1) op0 = adjust_address_nv (op0, mode1, 0); @@ -4544,17 +4539,18 @@ expand_debug_expr (tree exp) set_mem_attributes (op0, exp, 0); } - if (bitpos == 0 && mode == GET_MODE (op0)) + if (known_eq (bitpos, 0) && mode == GET_MODE (op0)) return op0; - if (bitpos < 0) + if (maybe_lt (bitpos, 0)) return NULL; if (GET_MODE (op0) == BLKmode) return NULL; - if ((bitpos % BITS_PER_UNIT) == 0 - && bitsize == GET_MODE_BITSIZE (mode1)) + poly_int64 bytepos; + if (multiple_p (bitpos, BITS_PER_UNIT, &bytepos) + && known_eq (bitsize, GET_MODE_BITSIZE (mode1))) { machine_mode opmode = GET_MODE (op0); @@ -4567,12 +4563,11 @@ expand_debug_expr (tree exp) debug stmts). The gen_subreg below would rightfully crash, and the address doesn't really exist, so just drop it. */ - if (bitpos >= GET_MODE_BITSIZE (opmode)) + if (known_ge (bitpos, GET_MODE_BITSIZE (opmode))) return NULL; - if ((bitpos % GET_MODE_BITSIZE (mode)) == 0) - return simplify_gen_subreg (mode, op0, opmode, - bitpos / BITS_PER_UNIT); + if (multiple_p (bitpos, GET_MODE_BITSIZE (mode))) + return simplify_gen_subreg (mode, op0, opmode, bytepos); } return simplify_gen_ternary (SCALAR_INT_MODE_P (GET_MODE (op0)) @@ -4582,7 +4577,8 @@ expand_debug_expr (tree exp) GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : TYPE_MODE (TREE_TYPE (tem)), - op0, GEN_INT (bitsize), GEN_INT (bitpos)); + op0, gen_int_mode (bitsize, word_mode), + gen_int_mode (bitpos, word_mode)); } case ABS_EXPR: @@ -5638,6 +5638,17 @@ extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree); the access position and size. */ extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, tree *, machine_mode *, int *, int *, int *); +/* Temporary. */ +inline tree +get_inner_reference (tree exp, poly_int64_pod *pbitsize, + poly_int64_pod *pbitpos, tree *poffset, + machine_mode *pmode, int *punsignedp, + int *preversep, int *pvolatilep) +{ + return get_inner_reference (exp, &pbitsize->coeffs[0], &pbitpos->coeffs[0], + poffset, pmode, punsignedp, preversep, + pvolatilep); +} extern tree build_personality_function (const char *); |