flowmap: improve debug graph output. NFC.

This commit is contained in:
whitequark 2019-01-04 02:46:27 +00:00
parent 7850a0c28a
commit fd21564deb
1 changed files with 76 additions and 47 deletions

View File

@ -64,10 +64,10 @@ PRIVATE_NAMESPACE_BEGIN
struct GraphStyle
{
string label;
string color;
string color, fillcolor;
GraphStyle(string label = "", string color = "black") :
label(label), color(color) {}
GraphStyle(string label = "", string color = "black", string fillcolor = "") :
label(label), color(color), fillcolor(fillcolor) {}
};
static string dot_escape(string value)
@ -110,13 +110,11 @@ static void dump_dot_graph(string filename,
if (outputs[node])
shape = "octagon";
auto prop = node_style(node);
string id;
if (node == SigBit())
id = "(source)";
else
id = log_signal(node);
fprintf(f, " n%d [ shape=%s, fontname=\"Monospace\", label=\"%s%s\", color=\"%s\" ];\n",
ids[node], shape.c_str(), dot_escape(id).c_str(), dot_escape(prop.label.c_str()).c_str(), prop.color.c_str());
string style = "";
if (!prop.fillcolor.empty())
style = "filled";
fprintf(f, " n%d [ shape=%s, fontname=\"Monospace\", label=\"%s\", color=\"%s\", fillcolor=\"%s\", style=\"%s\" ];\n",
ids[node], shape.c_str(), dot_escape(prop.label.c_str()).c_str(), prop.color.c_str(), prop.fillcolor.c_str(), style.c_str());
}
fprintf(f, " { rank=\"source\"; ");
@ -138,8 +136,8 @@ static void dump_dot_graph(string filename,
if (nodes[source] && nodes[sink])
{
auto prop = edge_style(source, sink);
fprintf(f, " n%d -> n%d [ label=\"%s\", color=\"%s\" ];\n",
ids[source], ids[sink], dot_escape(prop.label.c_str()).c_str(), prop.color.c_str());
fprintf(f, " n%d -> n%d [ label=\"%s\", color=\"%s\", fillcolor=\"%s\" ];\n",
ids[source], ids[sink], dot_escape(prop.label.c_str()).c_str(), prop.color.c_str(), prop.fillcolor.c_str());
}
}
}
@ -164,7 +162,7 @@ struct FlowGraph
void dump_dot_graph(string filename)
{
auto node_style = [&](RTLIL::SigBit node) {
string label;
string label = (node == source) ? "(source)" : log_signal(node);
for (auto collapsed_node : collapsed[node])
label += stringf(" %s", log_signal(collapsed_node));
int flow = node_flow[node];
@ -423,28 +421,46 @@ struct FlowmapWorker
int mapped_count = 0, packed_count = 0, unique_packed_count = 0;
void dump_dot_graph(string filename, pool<RTLIL::SigBit> subgraph = {}, pair<pool<RTLIL::SigBit>, pool<RTLIL::SigBit>> cut = {})
void dump_dot_graph(string filename,
pool<RTLIL::SigBit> subgraph_nodes = {}, dict<RTLIL::SigBit, pool<RTLIL::SigBit>> subgraph_edges = {},
pair<pool<RTLIL::SigBit>, pool<RTLIL::SigBit>> cut = {},
dict<RTLIL::SigBit, pool<RTLIL::SigBit>> collapsed = {})
{
if (subgraph.empty())
subgraph = nodes;
if (subgraph_nodes.empty())
subgraph_nodes = nodes;
if (subgraph_edges.empty())
subgraph_edges = edges_fw;
auto node_style = [&](RTLIL::SigBit node) {
string label, color;
string label = log_signal(node);
for (auto collapsed_node : collapsed[node])
if (collapsed_node != node)
label += stringf(" %s", log_signal(collapsed_node));
if (labels[node] == -1)
label = string("\n<unlabeled>");
label += "\nl=?";
else
label = stringf("\nl=%d", labels[node]);
color = "black";
if (cut.first[node])
color = "blue";
if (cut.second[node])
color = "red";
return GraphStyle{label, color};
label += stringf("\nl=%d", labels[node]);
if (cut.first.empty() && cut.second.empty())
{
if (labels[node] == -1)
return GraphStyle{label};
string fillcolor = stringf("/set311/%d", 1 + labels[node] % 11);
return GraphStyle{label, "", fillcolor};
}
else
{
string color = "black";
if (cut.first[node])
color = "blue";
if (cut.second[node])
color = "red";
return GraphStyle{label, color};
}
};
auto edge_style = [&](RTLIL::SigBit, RTLIL::SigBit) {
return GraphStyle{};
};
::dump_dot_graph(filename, subgraph, edges_fw, inputs, outputs, node_style, edge_style, module->name.str());
::dump_dot_graph(filename, subgraph_nodes, subgraph_edges, inputs, outputs, node_style, edge_style, module->name.str());
}
pool<RTLIL::SigBit> find_subgraph(RTLIL::SigBit sink)
@ -582,8 +598,8 @@ struct FlowmapWorker
if (debug)
{
dump_dot_graph("flowmap-init.dot");
log("Dumped complete combinatorial graph to `flowmap-init.dot`.\n");
dump_dot_graph("flowmap-initial.dot");
log("Dumped complete initial graph to `flowmap-initial.dot`.\n");
}
pool<RTLIL::SigBit> worklist = nodes;
@ -650,7 +666,7 @@ struct FlowmapWorker
if (debug)
{
log(" Maximum flow: %d. Assigned label %d.\n", flow, labels[sink]);
dump_dot_graph(stringf("flowmap-%d-sub.dot", debug_num), subgraph, {x, xi});
dump_dot_graph(stringf("flowmap-%d-sub.dot", debug_num), subgraph, {}, {x, xi});
log(" Dumped subgraph to `flowmap-%d-sub.dot`.\n", debug_num);
flow_graph.dump_dot_graph(stringf("flowmap-%d-flow.dot", debug_num));
log(" Dumped flow graph to `flowmap-%d-flow.dot`.\n", debug_num);
@ -668,17 +684,40 @@ struct FlowmapWorker
worklist.insert(sink_succ);
}
if (debug)
{
dump_dot_graph("flowmap-done.dot");
log("Dumped complete combinatorial graph to `flowmap-done.dot`.\n");
}
int depth = 0;
for (auto label : labels)
depth = max(depth, label.second);
log("Maximum depth: %d levels.\n", depth);
if (debug)
{
dump_dot_graph("flowmap-labeled.dot");
log("Dumped complete labeled graph to `flowmap-labeled.dot`.\n");
}
pool<RTLIL::SigBit> lut_nodes;
dict<RTLIL::SigBit, pool<RTLIL::SigBit>> lut_edges;
worklist = outputs;
while (!worklist.empty())
{
auto lut_node = worklist.pop();
lut_nodes.insert(lut_node);
for (auto input_node : lut_inputs[lut_node])
{
lut_edges[input_node].insert(lut_node);
if (!lut_nodes[input_node] && !inputs[input_node])
worklist.insert(input_node);
}
}
if (debug)
{
pool<RTLIL::SigBit> lut_and_input_nodes = lut_nodes;
lut_and_input_nodes.insert(inputs.begin(), inputs.end());
dump_dot_graph("flowmap-packed.dot", lut_and_input_nodes, lut_edges, {}, lut_gates);
log("Dumped complete packed graph to `flowmap-packed.dot`.\n");
}
ConstEval ce(module);
for (auto input_node : inputs)
ce.stop(input_node);
@ -687,10 +726,8 @@ struct FlowmapWorker
log("Mapping cells.\n");
pool<RTLIL::SigBit> mapped_nodes;
worklist = outputs;
while (!worklist.empty())
for (auto node : lut_nodes)
{
auto node = worklist.pop();
if (node_origins.count(node))
{
auto origin = node_origins[node];
@ -750,22 +787,14 @@ struct FlowmapWorker
RTLIL::Cell *lut = module->addLut(NEW_ID, lut_a, lut_y, lut_table);
mapped_count++;
mapped_nodes.insert(node);
for (auto gate_node : lut_gates[node])
{
auto gate_origin = node_origins[gate_node];
lut->add_strpool_attribute("\\src", gate_origin.cell->get_strpool_attribute("\\src"));
packed_count++;
}
log(" Packed into a %d-LUT %s.%s.\n", (int)input_nodes.size(), log_id(module), log_id(lut));
mapped_nodes.insert(node);
for (auto input_node : input_nodes)
{
if (!mapped_nodes[input_node] && !inputs[input_node])
worklist.insert(input_node);
}
}
unique_packed_count += nodes.size();