[PATCH] Speed up get_ref_base_and_extent
Richard Guenther
rguenther@suse.de
Tue Mar 27 14:50:00 GMT 2007
This patch speeds up get_ref_base_and_extent significantly as I just
noticed that it's on top of the profile for tramp3d:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
2.62 1.95 1.95 25982327 0.00 0.00 ggc_alloc_stat
2.35 3.69 1.75 3090386 0.00 0.00 gt_ggc_mx_lang_tree_node
2.05 5.21 1.52 51215344 0.00 0.00 ggc_set_mark
1.92 6.63 1.42 19137523 0.00 0.00 mul_double_with_sign
this is because we use trees to track the (constant) bit offset which
we get from (constant) byte offsets by multiplying with BITS_PER_UNIT...
Luckily we don't check for overflow now, but just take the lower part
of the resulting bit_offset to store it into the return location.
So this patch doesn't change this part but only exchanges all the
intermediate computation to work on HOST_WIDE_INTs instead. Which gives
us
0.02 55.64 0.01 239633 0.00 0.00 mul_double_with_sign
way down on the radar (and we might be able to save some memory on
tree int nodes as well).
Bootstrapped on x86_64-unknown-linux-gnu, I'll apply this to
mainline after testing finished.
If somebody is concerned about bit_offset overflowing I can incrementally
fix this by tracking the bit part of the offset separately so the maximum
allowed (byte) offset will be max (HOST_WIDE_INT) which is reasonable.
Of course having a TARGET_SIZE_TYPE_WIDE_INT would be nice here ;)
Richard.
2007-03-27 Richard Guenther <rguenther@suse.de>
* tree-dfa.c (get_ref_base_and_extent): Replace bit_offset and
computations with it with a HOST_WIDE_INT variable.
Index: tree-dfa.c
===================================================================
*** tree-dfa.c (revision 123218)
--- tree-dfa.c (working copy)
*************** get_ref_base_and_extent (tree exp, HOST_
*** 859,865 ****
HOST_WIDE_INT bitsize = -1;
HOST_WIDE_INT maxsize = -1;
tree size_tree = NULL_TREE;
! tree bit_offset = bitsize_zero_node;
bool seen_variable_array_ref = false;
gcc_assert (!SSA_VAR_P (exp));
--- 859,865 ----
HOST_WIDE_INT bitsize = -1;
HOST_WIDE_INT maxsize = -1;
tree size_tree = NULL_TREE;
! HOST_WIDE_INT bit_offset = 0;
bool seen_variable_array_ref = false;
gcc_assert (!SSA_VAR_P (exp));
*************** get_ref_base_and_extent (tree exp, HOST_
*** 896,903 ****
switch (TREE_CODE (exp))
{
case BIT_FIELD_REF:
! bit_offset = size_binop (PLUS_EXPR, bit_offset,
! TREE_OPERAND (exp, 2));
break;
case COMPONENT_REF:
--- 896,902 ----
switch (TREE_CODE (exp))
{
case BIT_FIELD_REF:
! bit_offset += tree_low_cst (TREE_OPERAND (exp, 2), 1);
break;
case COMPONENT_REF:
*************** get_ref_base_and_extent (tree exp, HOST_
*** 907,920 ****
if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
{
! this_offset = size_binop (MULT_EXPR,
! fold_convert (bitsizetype,
! this_offset),
! bitsize_unit_node);
! bit_offset = size_binop (PLUS_EXPR,
! bit_offset, this_offset);
! bit_offset = size_binop (PLUS_EXPR, bit_offset,
! DECL_FIELD_BIT_OFFSET (field));
}
else
{
--- 906,916 ----
if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
{
! HOST_WIDE_INT hthis_offset = tree_low_cst (this_offset, 1);
!
! hthis_offset *= BITS_PER_UNIT;
! bit_offset += hthis_offset;
! bit_offset += tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1);
}
else
{
*************** get_ref_base_and_extent (tree exp, HOST_
*** 925,932 ****
if (maxsize != -1
&& csize && host_integerp (csize, 1))
{
! maxsize = (TREE_INT_CST_LOW (csize)
! - TREE_INT_CST_LOW (bit_offset));
}
else
maxsize = -1;
--- 921,927 ----
if (maxsize != -1
&& csize && host_integerp (csize, 1))
{
! maxsize = (TREE_INT_CST_LOW (csize) - bit_offset);
}
else
maxsize = -1;
*************** get_ref_base_and_extent (tree exp, HOST_
*** 941,957 ****
tree low_bound = array_ref_low_bound (exp);
tree unit_size = array_ref_element_size (exp);
! if (! integer_zerop (low_bound))
! index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
! index, low_bound);
! index = size_binop (MULT_EXPR,
! fold_convert (sizetype, index), unit_size);
! if (TREE_CODE (index) == INTEGER_CST)
{
! index = size_binop (MULT_EXPR,
! fold_convert (bitsizetype, index),
! bitsize_unit_node);
! bit_offset = size_binop (PLUS_EXPR, bit_offset, index);
/* An array ref with a constant index up in the structure
hierarchy will constrain the size of any variable array ref
--- 936,952 ----
tree low_bound = array_ref_low_bound (exp);
tree unit_size = array_ref_element_size (exp);
! /* If the resulting bit-offset is constant, track it. */
! if (host_integerp (index, 0)
! && host_integerp (low_bound, 0)
! && host_integerp (unit_size, 1))
{
! HOST_WIDE_INT hindex = tree_low_cst (index, 0);
!
! hindex -= tree_low_cst (low_bound, 0);
! hindex *= tree_low_cst (unit_size, 1);
! hindex *= BITS_PER_UNIT;
! bit_offset += hindex;
/* An array ref with a constant index up in the structure
hierarchy will constrain the size of any variable array ref
*************** get_ref_base_and_extent (tree exp, HOST_
*** 967,974 ****
if (maxsize != -1
&& asize && host_integerp (asize, 1))
{
! maxsize = (TREE_INT_CST_LOW (asize)
! - TREE_INT_CST_LOW (bit_offset));
}
else
maxsize = -1;
--- 962,968 ----
if (maxsize != -1
&& asize && host_integerp (asize, 1))
{
! maxsize = (TREE_INT_CST_LOW (asize) - bit_offset);
}
else
maxsize = -1;
*************** get_ref_base_and_extent (tree exp, HOST_
*** 984,991 ****
break;
case IMAGPART_EXPR:
! bit_offset = size_binop (PLUS_EXPR, bit_offset,
! bitsize_int (bitsize));
break;
case VIEW_CONVERT_EXPR:
--- 978,984 ----
break;
case IMAGPART_EXPR:
! bit_offset += bitsize;
break;
case VIEW_CONVERT_EXPR:
*************** get_ref_base_and_extent (tree exp, HOST_
*** 1011,1024 ****
if (seen_variable_array_ref
&& maxsize != -1
&& host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
! && TREE_INT_CST_LOW (bit_offset) + maxsize
! == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))
maxsize = -1;
/* ??? Due to negative offsets in ARRAY_REF we can end up with
negative bit_offset here. We might want to store a zero offset
in this case. */
! *poffset = TREE_INT_CST_LOW (bit_offset);
*psize = bitsize;
*pmax_size = maxsize;
--- 1004,1017 ----
if (seen_variable_array_ref
&& maxsize != -1
&& host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
! && bit_offset + maxsize
! == (signed)TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))
maxsize = -1;
/* ??? Due to negative offsets in ARRAY_REF we can end up with
negative bit_offset here. We might want to store a zero offset
in this case. */
! *poffset = bit_offset;
*psize = bitsize;
*pmax_size = maxsize;
More information about the Gcc-patches
mailing list