mirror of
https://github.com/YosysHQ/yosys
synced 2025-09-16 14:41:33 +00:00
Optimize Const::hash_into to hash packed bits efficiently
This commit is contained in:
parent
7814aa0c31
commit
c2ad2a407a
3 changed files with 47 additions and 6 deletions
|
@ -723,6 +723,40 @@ bool RTLIL::Const::is_onehot(int *pos) const
|
||||||
return found;
|
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 {
|
RTLIL::Const RTLIL::Const::extract(int offset, int len, RTLIL::State padding) const {
|
||||||
bitvectype ret_bv;
|
bitvectype ret_bv;
|
||||||
ret_bv.reserve(len);
|
ret_bv.reserve(len);
|
||||||
|
|
|
@ -953,12 +953,7 @@ public:
|
||||||
resize(width, empty() ? RTLIL::State::Sx : back());
|
resize(width, empty() ? RTLIL::State::Sx : back());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Hasher hash_into(Hasher h) const {
|
[[nodiscard]] Hasher hash_into(Hasher h) const;
|
||||||
h.eat(size());
|
|
||||||
for (auto b : *this)
|
|
||||||
h.eat(b);
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RTLIL::AttrObject
|
struct RTLIL::AttrObject
|
||||||
|
|
|
@ -222,6 +222,18 @@ namespace RTLIL {
|
||||||
EXPECT_NE(Const(v1), Const("a"));
|
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 :
|
class WireRtlVsHdlIndexConversionTest :
|
||||||
public KernelRtlilTest,
|
public KernelRtlilTest,
|
||||||
public testing::WithParamInterface<std::tuple<bool, int, int>>
|
public testing::WithParamInterface<std::tuple<bool, int, int>>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue