From: Rick Altherr Date: Sun, 31 Jan 2016 17:07:21 +0000 (-0800) Subject: rtlil: Improve performance of SigSpec::extract(SigSpec, SigSpec*) X-Git-Tag: yosys-0.6~30^2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3c48de8e218ff70f4b5f8e42a6794a48354ea062;p=yosys.git rtlil: Improve performance of SigSpec::extract(SigSpec, SigSpec*) Converting to a pool is fairly expensive due to inserts somewhat frequently causing rehashing. Instead, walk through the pattern SigSpec directly on a chunk-by-chunk basis and apply it to this SigSpec's individual bits. Using chunks for the pattern minimizes the number of iterations in the outer loop. --- diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index ee0f44a38..1f3f78999 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -2777,8 +2777,37 @@ void RTLIL::SigSpec::remove2(const std::set &pattern, RTLIL::SigS RTLIL::SigSpec RTLIL::SigSpec::extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other) const { - pool pattern_bits = pattern.to_sigbit_pool(); - return extract(pattern_bits, other); + if (other) + cover("kernel.rtlil.sigspec.extract_other"); + else + cover("kernel.rtlil.sigspec.extract"); + + log_assert(other == NULL || width_ == other->width_); + + RTLIL::SigSpec ret; + std::vector bits_match = to_sigbit_vector(); + + for (auto& pattern_chunk : pattern.chunks()) { + if (other) { + std::vector bits_other = other->to_sigbit_vector(); + for (int i = 0; i < width_; i++) + if (bits_match[i].wire && + bits_match[i].wire == pattern_chunk.wire && + bits_match[i].offset >= pattern_chunk.offset && + bits_match[i].offset < pattern_chunk.offset + pattern_chunk.width) + ret.append_bit(bits_other[i]); + } else { + for (int i = 0; i < width_; i++) + if (bits_match[i].wire && + bits_match[i].wire == pattern_chunk.wire && + bits_match[i].offset >= pattern_chunk.offset && + bits_match[i].offset < pattern_chunk.offset + pattern_chunk.width) + ret.append_bit(bits_match[i]); + } + } + + ret.check(); + return ret; } RTLIL::SigSpec RTLIL::SigSpec::extract(const pool &pattern, const RTLIL::SigSpec *other) const