From 06889da8cc1feb59b65058c51e224bf78248781a Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 20 Dec 2017 12:56:24 +0000 Subject: [PATCH] poly_int: expand_debug_expr This patch makes expand_debug_expr track polynomial memory offsets. It simplifies the handling of the case in which the reference is not to the first byte of the base, which seemed non-trivial enough to make it worth splitting out as a separate patch. 2017-12-20 Richard Sandiford Alan Hayward David Sherwood gcc/ * 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. Co-Authored-By: Alan Hayward Co-Authored-By: David Sherwood From-SVN: r255892 --- gcc/ChangeLog | 9 +++++++++ gcc/cfgexpand.c | 40 ++++++++++++++++++---------------------- gcc/tree.h | 11 +++++++++++ 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 70e8c1a5e46..3aca9c59ccd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-12-20 Richard Sandiford + Alan Hayward + David Sherwood + + * 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 Alan Hayward David Sherwood diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 324e0972b50..d509326b9e6 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: diff --git a/gcc/tree.h b/gcc/tree.h index a7b8c2f400c..db873218827 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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 *); -- 2.30.2