Skip to content

Commit 6510982

Browse files
authored
Merge pull request #5305 from rocallahan/opt-merge-perf
Use commutative hashing in `OptMergePass` instead of allocating containers and sorting them to get canonical hashes
2 parents d101906 + 8c04e52 commit 6510982

File tree

1 file changed

+20
-39
lines changed

1 file changed

+20
-39
lines changed

passes/opt/opt_merge.cc

Lines changed: 20 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,16 @@ struct OptMergeWorker
4444
CellTypes ct;
4545
int total_count;
4646

47-
static vector<pair<SigBit, SigSpec>> sorted_pmux_in(const dict<RTLIL::IdString, RTLIL::SigSpec> &conn)
47+
static Hasher hash_pmux_in(const SigSpec& sig_s, const SigSpec& sig_b, Hasher h)
4848
{
49-
SigSpec sig_s = conn.at(ID::S);
50-
SigSpec sig_b = conn.at(ID::B);
51-
5249
int s_width = GetSize(sig_s);
5350
int width = GetSize(sig_b) / s_width;
5451

55-
vector<pair<SigBit, SigSpec>> sb_pairs;
52+
hashlib::commutative_hash comm;
5653
for (int i = 0; i < s_width; i++)
57-
sb_pairs.push_back(pair<SigBit, SigSpec>(sig_s[i], sig_b.extract(i*width, width)));
54+
comm.eat(hash_ops<std::pair<SigBit, SigSpec>>::hash({sig_s[i], sig_b.extract(i*width, width)}));
5855

59-
std::sort(sb_pairs.begin(), sb_pairs.end());
60-
return sb_pairs;
56+
return comm.hash_into(h);
6157
}
6258

6359
static void sort_pmux_conn(dict<RTLIL::IdString, RTLIL::SigSpec> &conn)
@@ -89,12 +85,10 @@ struct OptMergeWorker
8985
// (builtin || stdcell) && (unary || binary) && symmetrical
9086
if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($mul),
9187
ID($logic_and), ID($logic_or), ID($_AND_), ID($_OR_), ID($_XOR_))) {
92-
std::array<RTLIL::SigSpec, 2> inputs = {
93-
assign_map(cell->getPort(ID::A)),
94-
assign_map(cell->getPort(ID::B))
95-
};
96-
std::sort(inputs.begin(), inputs.end());
97-
h = hash_ops<std::array<RTLIL::SigSpec, 2>>::hash_into(inputs, h);
88+
hashlib::commutative_hash comm;
89+
comm.eat(hash_ops<RTLIL::SigSpec>::hash(assign_map(cell->getPort(ID::A))));
90+
comm.eat(hash_ops<RTLIL::SigSpec>::hash(assign_map(cell->getPort(ID::B))));
91+
h = comm.hash_into(h);
9892
} else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) {
9993
SigSpec a = assign_map(cell->getPort(ID::A));
10094
a.sort();
@@ -104,44 +98,31 @@ struct OptMergeWorker
10498
a.sort_and_unify();
10599
h = a.hash_into(h);
106100
} else if (cell->type == ID($pmux)) {
107-
dict<RTLIL::IdString, RTLIL::SigSpec> conn = cell->connections();
108-
assign_map.apply(conn.at(ID::A));
109-
assign_map.apply(conn.at(ID::B));
110-
assign_map.apply(conn.at(ID::S));
111-
for (const auto& [s_bit, b_chunk] : sorted_pmux_in(conn)) {
112-
h = s_bit.hash_into(h);
113-
h = b_chunk.hash_into(h);
114-
}
101+
SigSpec sig_s = assign_map(cell->getPort(ID::S));
102+
SigSpec sig_b = assign_map(cell->getPort(ID::B));
103+
h = hash_pmux_in(sig_s, sig_b, h);
115104
h = assign_map(cell->getPort(ID::A)).hash_into(h);
116105
} else {
117-
std::vector<std::pair<IdString, SigSpec>> conns;
118-
for (const auto& conn : cell->connections()) {
119-
conns.push_back(conn);
120-
}
121-
std::sort(conns.begin(), conns.end());
122-
for (const auto& [port, sig] : conns) {
123-
if (!cell->output(port)) {
124-
h = port.hash_into(h);
125-
h = assign_map(sig).hash_into(h);
126-
}
106+
hashlib::commutative_hash comm;
107+
for (const auto& [port, sig] : cell->connections()) {
108+
if (cell->output(port))
109+
continue;
110+
comm.eat(hash_ops<std::pair<IdString, SigSpec>>::hash({port, assign_map(sig)}));
127111
}
128-
112+
h = comm.hash_into(h);
129113
if (RTLIL::builtin_ff_cell_types().count(cell->type))
130114
h = initvals(cell->getPort(ID::Q)).hash_into(h);
131-
132115
}
133116
return h;
134117
}
135118

136119
static Hasher hash_cell_parameters(const RTLIL::Cell *cell, Hasher h)
137120
{
138-
using Paramvec = std::vector<std::pair<IdString, Const>>;
139-
Paramvec params;
121+
hashlib::commutative_hash comm;
140122
for (const auto& param : cell->parameters) {
141-
params.push_back(param);
123+
comm.eat(hash_ops<std::pair<IdString, Const>>::hash(param));
142124
}
143-
std::sort(params.begin(), params.end());
144-
return hash_ops<Paramvec>::hash_into(params, h);
125+
return comm.hash_into(h);
145126
}
146127

147128
Hasher hash_cell_function(const RTLIL::Cell *cell, Hasher h) const

0 commit comments

Comments
 (0)