rtlil: speed up SigSpec::sort_and_unify()
authorRick Altherr <kc8apf@kc8apf.net>
Sun, 31 Jan 2016 16:55:49 +0000 (08:55 -0800)
committerRick Altherr <kc8apf@kc8apf.net>
Sun, 31 Jan 2016 17:20:16 +0000 (09:20 -0800)
std::set<> internally is often a red-black tree which is fairly
expensive to create but fast to lookup.  In the case of
sort_and_unify(), a set<> is constructed as a temporary object to
attempt to speed up lookups.  Being a temporarily, however, the cost of
creation far outweights the lookup improvement and is a net performance
loss.  Instead, sort the vector<> that already exists and then apply
std::unique().

kernel/rtlil.cc

index ca4480576936a9276b7eec73b84a03c8aa17e117..ee0f44a38a3d8bd4a2496a5495f6f2d0de921253 100644 (file)
@@ -2573,8 +2573,18 @@ void RTLIL::SigSpec::sort()
 
 void RTLIL::SigSpec::sort_and_unify()
 {
+       unpack();
        cover("kernel.rtlil.sigspec.sort_and_unify");
-       *this = this->to_sigbit_set();
+
+       // A copy of the bits vector is used to prevent duplicating the logic from
+       // SigSpec::SigSpec(std::vector<SigBit>).  This incurrs an extra copy but
+       // that isn't showing up as significant in profiles.
+       std::vector<SigBit> unique_bits = bits_;
+       std::sort(unique_bits.begin(), unique_bits.end());
+       auto last = std::unique(unique_bits.begin(), unique_bits.end());
+       unique_bits.erase(last, unique_bits.end());
+
+       *this = unique_bits;
 }
 
 void RTLIL::SigSpec::replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)