aboutsummaryrefslogtreecommitdiff
path: root/gcc/value-range.h
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2023-07-14 12:16:17 +0200
committerAldy Hernandez <aldyh@redhat.com>2023-07-17 09:17:59 +0200
commit56cf8b01fe1d4d4bb33a107e5d490f589d5f05bc (patch)
treea6f850cc864497e4f67fb69a79b9ad506054e39b /gcc/value-range.h
parent0407ae8a7732d90622a65ddf1798c9d51d450e9d (diff)
downloadgcc-56cf8b01fe1d4d4bb33a107e5d490f589d5f05bc.zip
gcc-56cf8b01fe1d4d4bb33a107e5d490f589d5f05bc.tar.gz
gcc-56cf8b01fe1d4d4bb33a107e5d490f589d5f05bc.tar.bz2
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.
Diffstat (limited to 'gcc/value-range.h')
-rw-r--r--gcc/value-range.h12
1 files changed, 10 insertions, 2 deletions
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 0170188..d8af6fc 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -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