Normalize irange_bitmask before union/intersect.

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.
This commit is contained in:
Aldy Hernandez 2023-07-14 12:16:17 +02:00
parent 0407ae8a77
commit 56cf8b01fe
2 changed files with 10 additions and 5 deletions

View file

@ -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

View file

@ -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