mirror of
https://github.com/YosysHQ/yosys
synced 2025-08-22 19:17:55 +00:00
Merge pull request #5290 from rocallahan/opt-mux-perf
Make `OptMuxtreePass` int-indexed vectors into hashtables
This commit is contained in:
commit
025d7a5641
1 changed files with 28 additions and 20 deletions
|
@ -23,6 +23,8 @@
|
||||||
#include "kernel/celltypes.h"
|
#include "kernel/celltypes.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
USING_YOSYS_NAMESPACE
|
USING_YOSYS_NAMESPACE
|
||||||
|
@ -291,14 +293,14 @@ struct OptMuxtreeWorker
|
||||||
// database of known inactive signals
|
// database of known inactive signals
|
||||||
// the payload is a reference counter used to manage the
|
// the payload is a reference counter used to manage the
|
||||||
// list. when it is non-zero the signal in known to be inactive
|
// list. when it is non-zero the signal in known to be inactive
|
||||||
vector<int> known_inactive;
|
std::unordered_map<int, int> known_inactive;
|
||||||
|
|
||||||
// database of known active signals
|
// database of known active signals
|
||||||
vector<int> known_active;
|
std::unordered_map<int, int> known_active;
|
||||||
|
|
||||||
// this is just used to keep track of visited muxes in order to prohibit
|
// this is just used to keep track of visited muxes in order to prohibit
|
||||||
// endless recursion in mux loops
|
// endless recursion in mux loops
|
||||||
vector<bool> visited_muxes;
|
std::unordered_set<int> visited_muxes;
|
||||||
};
|
};
|
||||||
|
|
||||||
void eval_mux_port(knowledge_t &knowledge, int mux_idx, int port_idx, bool do_replace_known, bool do_enable_ports, int abort_count)
|
void eval_mux_port(knowledge_t &knowledge, int mux_idx, int port_idx, bool do_replace_known, bool do_enable_ports, int abort_count)
|
||||||
|
@ -315,17 +317,18 @@ struct OptMuxtreeWorker
|
||||||
if (i == port_idx)
|
if (i == port_idx)
|
||||||
continue;
|
continue;
|
||||||
if (muxinfo.ports[i].ctrl_sig >= 0)
|
if (muxinfo.ports[i].ctrl_sig >= 0)
|
||||||
knowledge.known_inactive.at(muxinfo.ports[i].ctrl_sig)++;
|
++knowledge.known_inactive[muxinfo.ports[i].ctrl_sig];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port_idx < GetSize(muxinfo.ports)-1 && !muxinfo.ports[port_idx].const_activated)
|
if (port_idx < GetSize(muxinfo.ports)-1 && !muxinfo.ports[port_idx].const_activated)
|
||||||
knowledge.known_active.at(muxinfo.ports[port_idx].ctrl_sig)++;
|
++knowledge.known_active[muxinfo.ports[port_idx].ctrl_sig];
|
||||||
|
|
||||||
vector<int> parent_muxes;
|
vector<int> parent_muxes;
|
||||||
for (int m : muxinfo.ports[port_idx].input_muxes) {
|
for (int m : muxinfo.ports[port_idx].input_muxes) {
|
||||||
if (knowledge.visited_muxes[m])
|
auto it = knowledge.visited_muxes.find(m);
|
||||||
|
if (it != knowledge.visited_muxes.end())
|
||||||
continue;
|
continue;
|
||||||
knowledge.visited_muxes[m] = true;
|
knowledge.visited_muxes.insert(it, m);
|
||||||
parent_muxes.push_back(m);
|
parent_muxes.push_back(m);
|
||||||
}
|
}
|
||||||
for (int m : parent_muxes) {
|
for (int m : parent_muxes) {
|
||||||
|
@ -344,16 +347,24 @@ struct OptMuxtreeWorker
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int m : parent_muxes)
|
for (int m : parent_muxes)
|
||||||
knowledge.visited_muxes[m] = false;
|
knowledge.visited_muxes.erase(m);
|
||||||
|
|
||||||
if (port_idx < GetSize(muxinfo.ports)-1 && !muxinfo.ports[port_idx].const_activated)
|
if (port_idx < GetSize(muxinfo.ports)-1 && !muxinfo.ports[port_idx].const_activated) {
|
||||||
knowledge.known_active.at(muxinfo.ports[port_idx].ctrl_sig)--;
|
auto it = knowledge.known_active.find(muxinfo.ports[port_idx].ctrl_sig);
|
||||||
|
if (it != knowledge.known_active.end())
|
||||||
|
if (--it->second == 0)
|
||||||
|
knowledge.known_active.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(muxinfo.ports); i++) {
|
for (int i = 0; i < GetSize(muxinfo.ports); i++) {
|
||||||
if (i == port_idx)
|
if (i == port_idx)
|
||||||
continue;
|
continue;
|
||||||
if (muxinfo.ports[i].ctrl_sig >= 0)
|
if (muxinfo.ports[i].ctrl_sig >= 0) {
|
||||||
knowledge.known_inactive.at(muxinfo.ports[i].ctrl_sig)--;
|
auto it = knowledge.known_inactive.find(muxinfo.ports[i].ctrl_sig);
|
||||||
|
if (it != knowledge.known_inactive.end())
|
||||||
|
if (--it->second == 0)
|
||||||
|
knowledge.known_inactive.erase(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,11 +384,11 @@ struct OptMuxtreeWorker
|
||||||
vector<int> bits = sig2bits(sig, false);
|
vector<int> bits = sig2bits(sig, false);
|
||||||
for (int i = 0; i < GetSize(bits); i++) {
|
for (int i = 0; i < GetSize(bits); i++) {
|
||||||
if (bits[i] >= 0) {
|
if (bits[i] >= 0) {
|
||||||
if (knowledge.known_inactive.at(bits[i])) {
|
if (knowledge.known_inactive.count(bits[i]) > 0) {
|
||||||
sig[i] = State::S0;
|
sig[i] = State::S0;
|
||||||
did_something = true;
|
did_something = true;
|
||||||
} else
|
} else
|
||||||
if (knowledge.known_active.at(bits[i])) {
|
if (knowledge.known_active.count(bits[i]) > 0) {
|
||||||
sig[i] = State::S1;
|
sig[i] = State::S1;
|
||||||
did_something = true;
|
did_something = true;
|
||||||
}
|
}
|
||||||
|
@ -435,7 +446,7 @@ struct OptMuxtreeWorker
|
||||||
portinfo_t &portinfo = muxinfo.ports[port_idx];
|
portinfo_t &portinfo = muxinfo.ports[port_idx];
|
||||||
if (portinfo.const_deactivated)
|
if (portinfo.const_deactivated)
|
||||||
continue;
|
continue;
|
||||||
if (knowledge.known_active.at(portinfo.ctrl_sig)) {
|
if (knowledge.known_active.count(portinfo.ctrl_sig) > 0) {
|
||||||
eval_mux_port(knowledge, mux_idx, port_idx, do_replace_known, do_enable_ports, abort_count);
|
eval_mux_port(knowledge, mux_idx, port_idx, do_replace_known, do_enable_ports, abort_count);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -449,7 +460,7 @@ struct OptMuxtreeWorker
|
||||||
if (portinfo.const_deactivated)
|
if (portinfo.const_deactivated)
|
||||||
continue;
|
continue;
|
||||||
if (port_idx < GetSize(muxinfo.ports)-1)
|
if (port_idx < GetSize(muxinfo.ports)-1)
|
||||||
if (knowledge.known_inactive.at(portinfo.ctrl_sig))
|
if (knowledge.known_inactive.count(portinfo.ctrl_sig) > 0)
|
||||||
continue;
|
continue;
|
||||||
eval_mux_port(knowledge, mux_idx, port_idx, do_replace_known, do_enable_ports, abort_count);
|
eval_mux_port(knowledge, mux_idx, port_idx, do_replace_known, do_enable_ports, abort_count);
|
||||||
|
|
||||||
|
@ -462,10 +473,7 @@ struct OptMuxtreeWorker
|
||||||
{
|
{
|
||||||
log_assert(glob_abort_cnt > 0);
|
log_assert(glob_abort_cnt > 0);
|
||||||
knowledge_t knowledge;
|
knowledge_t knowledge;
|
||||||
knowledge.known_inactive.resize(GetSize(bit2info));
|
knowledge.visited_muxes.insert(mux_idx);
|
||||||
knowledge.known_active.resize(GetSize(bit2info));
|
|
||||||
knowledge.visited_muxes.resize(GetSize(mux2info));
|
|
||||||
knowledge.visited_muxes[mux_idx] = true;
|
|
||||||
eval_mux(knowledge, mux_idx, true, root_enable_muxes.at(mux_idx), 3);
|
eval_mux(knowledge, mux_idx, true, root_enable_muxes.at(mux_idx), 3);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue