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:
parent
0407ae8a77
commit
56cf8b01fe
2 changed files with 10 additions and 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
|
||||
|
|
Loading…
Add table
Reference in a new issue