Commit 06889da8 by Richard Sandiford Committed by Richard Sandiford

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  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

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 <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r255892
parent a85d87b2
......@@ -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.
......@@ -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 *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment