3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-09-13 05:01:29 +00:00

Optimize Const::hash_into to hash packed bits efficiently

This commit is contained in:
Robert O'Callahan 2025-08-29 03:48:16 +00:00
parent 7814aa0c31
commit c2ad2a407a
3 changed files with 47 additions and 6 deletions

View file

@ -723,6 +723,40 @@ bool RTLIL::Const::is_onehot(int *pos) const
return found;
}
Hasher RTLIL::Const::hash_into(Hasher h) const
{
if (auto str = get_if_str())
return hashlib::hash_ops<std::string>::hash_into(*str, h);
// If the bits are all 0/1, hash packed bits using the string hash.
// Otherwise hash the leading packed bits with the rest of the bits individually.
bitvectype &bv = get_bits();
int size = GetSize(bv);
std::string packed;
int packed_size = (size + 7) >> 3;
packed.resize(packed_size, 0);
for (int bi = 0; bi < packed_size; ++bi) {
char ch = 0;
int end = std::min((bi + 1)*8, size);
for (int i = bi*8; i < end; ++i) {
RTLIL::State b = bv[i];
if (b > RTLIL::State::S1) {
// Hash the packed bits we've seen so far, plus the remaining bits.
h = hashlib::hash_ops<std::string>::hash_into(packed, h);
h = hashlib::hash_ops<char>::hash_into(ch, h);
for (; i < size; ++i) {
h = hashlib::hash_ops<RTLIL::State>::hash_into(bv[i], h);
}
h.eat(size);
return h;
}
ch |= static_cast<int>(b) << (i & 7);
}
packed[packed_size - 1 - bi] = ch;
}
return hashlib::hash_ops<std::string>::hash_into(packed, h);
}
RTLIL::Const RTLIL::Const::extract(int offset, int len, RTLIL::State padding) const {
bitvectype ret_bv;
ret_bv.reserve(len);

View file

@ -953,12 +953,7 @@ public:
resize(width, empty() ? RTLIL::State::Sx : back());
}
[[nodiscard]] Hasher hash_into(Hasher h) const {
h.eat(size());
for (auto b : *this)
h.eat(b);
return h;
}
[[nodiscard]] Hasher hash_into(Hasher h) const;
};
struct RTLIL::AttrObject

View file

@ -222,6 +222,18 @@ namespace RTLIL {
EXPECT_NE(Const(v1), Const("a"));
}
static Hasher::hash_t hash(const Const &c) {
Hasher h;
h = c.hash_into(h);
return h.yield();
}
TEST_F(KernelRtlilTest, ConstEqualHashStrBits) {
std::vector<State> v1 = {S0, S0, S0, S0, S0, S1, S0, S0};
EXPECT_EQ(hash(Const(v1)), hash(Const(" ")));
EXPECT_NE(hash(Const(v1)), hash(Const("a")));
}
class WireRtlVsHdlIndexConversionTest :
public KernelRtlilTest,
public testing::WithParamInterface<std::tuple<bool, int, int>>