This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Add TREE_INT_CST_OFFSET_NUNITS
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: zadeck at naturalbridge dot com, mikestump at comcast dot net
- Date: Sat, 30 Nov 2013 09:43:09 +0000
- Subject: Add TREE_INT_CST_OFFSET_NUNITS
- Authentication-results: sourceware.org; auth=none
So maybe two INTEGER_CST lengths weren't enough. Because bitsizetype
can be offset_int-sized, wi::to_offset had a TYPE_PRECISION condition
to pick the array length:
template <int N>
inline unsigned int
wi::extended_tree <N>::get_len () const
{
if (N == MAX_BITSIZE_MODE_ANY_INT
|| N > TYPE_PRECISION (TREE_TYPE (m_t)))
return TREE_INT_CST_EXT_NUNITS (m_t);
else
return TREE_INT_CST_NUNITS (m_t);
}
and this TYPE_PRECISION condition was relatively hot in
get_ref_base_and_extent when compiling insn-recog.ii.
Adding a third length for offset_int does seem to reduce the cost of
the offset_int + to_offset addition.
Tested on x86_64-linux-gnu. OK to install?
Thanks,
Richard
Index: gcc/ChangeLog.wide-int
===================================================================
--- gcc/ChangeLog.wide-int 2013-11-30 09:31:16.359198395 +0000
+++ gcc/ChangeLog.wide-int 2013-11-30 09:41:50.987741444 +0000
@@ -616,6 +616,7 @@
(TREE_INT_CST_HIGH): Delete.
(TREE_INT_CST_NUNITS): New.
(TREE_INT_CST_EXT_NUNITS): Likewise.
+ (TREE_INT_CST_OFFSET_NUNITS): Likewise.
(TREE_INT_CST_ELT): Likewise.
(INT_CST_LT): Use wide-int interfaces.
(INT_CST_LE): New.
Index: gcc/tree-core.h
===================================================================
--- gcc/tree-core.h 2013-11-30 09:31:16.359198395 +0000
+++ gcc/tree-core.h 2013-11-30 09:41:12.011470169 +0000
@@ -764,11 +764,16 @@ struct GTY(()) tree_base {
struct {
/* The number of HOST_WIDE_INTs if the INTEGER_CST is accessed in
its native precision. */
- unsigned short unextended;
+ unsigned char unextended;
/* The number of HOST_WIDE_INTs if the INTEGER_CST is extended to
wider precisions based on its TYPE_SIGN. */
- unsigned short extended;
+ unsigned char extended;
+
+ /* The number of HOST_WIDE_INTs if the INTEGER_CST is accessed in
+ offset_int precision, with smaller integers being extended
+ according to their TYPE_SIGN. */
+ unsigned char offset;
} int_length;
/* VEC length. This field is only used with TREE_VEC. */
Index: gcc/tree.c
===================================================================
--- gcc/tree.c 2013-11-30 09:31:16.359198395 +0000
+++ gcc/tree.c 2013-11-30 09:41:42.965685621 +0000
@@ -1285,6 +1285,7 @@ wide_int_to_tree (tree type, const wide_
/* Make sure no one is clobbering the shared constant. */
gcc_checking_assert (TREE_TYPE (t) == type
&& TREE_INT_CST_NUNITS (t) == 1
+ && TREE_INT_CST_OFFSET_NUNITS (t) == 1
&& TREE_INT_CST_EXT_NUNITS (t) == 1
&& TREE_INT_CST_ELT (t, 0) == hwi);
else
@@ -1964,6 +1965,7 @@ make_int_cst_stat (int len, int ext_len
TREE_SET_CODE (t, INTEGER_CST);
TREE_INT_CST_NUNITS (t) = len;
TREE_INT_CST_EXT_NUNITS (t) = ext_len;
+ TREE_INT_CST_OFFSET_NUNITS (t) = MIN (ext_len, OFFSET_INT_ELTS);
TREE_CONSTANT (t) = 1;
Index: gcc/tree.h
===================================================================
--- gcc/tree.h 2013-11-30 09:31:16.359198395 +0000
+++ gcc/tree.h 2013-11-30 09:41:29.418591391 +0000
@@ -907,6 +907,8 @@ #define TREE_INT_CST_NUNITS(NODE) \
(INTEGER_CST_CHECK (NODE)->base.u.int_length.unextended)
#define TREE_INT_CST_EXT_NUNITS(NODE) \
(INTEGER_CST_CHECK (NODE)->base.u.int_length.extended)
+#define TREE_INT_CST_OFFSET_NUNITS(NODE) \
+ (INTEGER_CST_CHECK (NODE)->base.u.int_length.offset)
#define TREE_INT_CST_ELT(NODE, I) TREE_INT_CST_ELT_CHECK (NODE, I)
#define TREE_INT_CST_LOW(NODE) \
((unsigned HOST_WIDE_INT) TREE_INT_CST_ELT (NODE, 0))
@@ -4623,8 +4625,10 @@ wi::extended_tree <N>::get_val () const
inline unsigned int
wi::extended_tree <N>::get_len () const
{
- if (N == MAX_BITSIZE_MODE_ANY_INT
- || N > TYPE_PRECISION (TREE_TYPE (m_t)))
+ if (N == ADDR_MAX_PRECISION)
+ return TREE_INT_CST_OFFSET_NUNITS (m_t);
+ else if (N == MAX_BITSIZE_MODE_ANY_INT
+ || N > TYPE_PRECISION (TREE_TYPE (m_t)))
return TREE_INT_CST_EXT_NUNITS (m_t);
else
return TREE_INT_CST_NUNITS (m_t);
Index: gcc/wide-int.h
===================================================================
--- gcc/wide-int.h 2013-11-30 09:31:16.359198395 +0000
+++ gcc/wide-int.h 2013-11-30 09:40:32.710196218 +0000
@@ -256,6 +256,9 @@ #define ADDR_MAX_BITSIZE 64
#define ADDR_MAX_PRECISION \
((ADDR_MAX_BITSIZE + 4 + HOST_BITS_PER_WIDE_INT - 1) & ~(HOST_BITS_PER_WIDE_INT - 1))
+/* The number of HWIs needed to store an offset_int. */
+#define OFFSET_INT_ELTS (ADDR_MAX_PRECISION / HOST_BITS_PER_WIDE_INT)
+
/* The type of result produced by a binary operation on types T1 and T2.
Defined purely for brevity. */
#define WI_BINARY_RESULT(T1, T2) \