[COMMITTED] Normalize irange_bitmask before union/intersect.
Checks
Commit Message
The bit twiddling in union/intersect for the value/mask pair must be
normalized to have the unknown bits with a value of 0 in order to make
the math simpler. Normalizing at construction slowed VRP by 1.5% so I
opted to normalize before updating the bitmask in range-ops, since it
was the only user. However, with upcoming changes there will be
multiple setters of the mask (IPA and CCP), so we need something more
general.
I played with various alternatives, and settled on normalizing before
union/intersect which were the ones needing the bits cleared. With
this patch, there's no noticeable difference in performance either in
VRP or in overall compilation.
gcc/ChangeLog:
* value-range.cc (irange_bitmask::verify_mask): Mask need not be
normalized.
* value-range.h (irange_bitmask::union_): Normalize beforehand.
(irange_bitmask::intersect): Same.
---
gcc/value-range.cc | 3 ---
gcc/value-range.h | 12 ++++++++++--
2 files changed, 10 insertions(+), 5 deletions(-)
@@ -1953,9 +1953,6 @@ void
irange_bitmask::verify_mask () const
{
gcc_assert (m_value.get_precision () == m_mask.get_precision ());
- // Unknown bits must have their corresponding value bits cleared as
- // it simplifies union and intersect.
- gcc_assert (wi::bit_and (m_mask, m_value) == 0);
}
void
@@ -211,8 +211,12 @@ irange_bitmask::operator== (const irange_bitmask &src) const
}
inline bool
-irange_bitmask::union_ (const irange_bitmask &src)
+irange_bitmask::union_ (const irange_bitmask &orig_src)
{
+ // Normalize mask.
+ irange_bitmask src (orig_src.m_value & ~orig_src.m_mask, orig_src.m_mask);
+ m_value &= ~m_mask;
+
irange_bitmask save (*this);
m_mask = (m_mask | src.m_mask) | (m_value ^ src.m_value);
m_value = m_value & src.m_value;
@@ -222,8 +226,12 @@ irange_bitmask::union_ (const irange_bitmask &src)
}
inline bool
-irange_bitmask::intersect (const irange_bitmask &src)
+irange_bitmask::intersect (const irange_bitmask &orig_src)
{
+ // Normalize mask.
+ irange_bitmask src (orig_src.m_value & ~orig_src.m_mask, orig_src.m_mask);
+ m_value &= ~m_mask;
+
irange_bitmask save (*this);
// If we have two known bits that are incompatible, the resulting
// bit is undefined. It is unclear whether we should set the entire