P4C
The P4 Compiler
Loading...
Searching...
No Matches
dump_table_flow_graph.h
1
19#ifndef BF_P4C_PHV_DUMP_TABLE_FLOW_GRAPH_H_
20#define BF_P4C_PHV_DUMP_TABLE_FLOW_GRAPH_H_
21
22#include "bf-p4c/mau/table_flow_graph.h"
23
24struct DumpTableFlowGraph : public Visitor {
25 const PhvInfo &phv;
26
27 explicit DumpTableFlowGraph(const PhvInfo &p) : phv(p) {}
28
30 const PhvInfo &phv;
31 explicit CollectPhvReadsAndWrites(const PhvInfo &p) : phv(p) {}
32
34
35 // An MAU::Table object may have TableSeq on the $default path,
36 // make sure these tables are not visited.
37 bool preorder(const IR::MAU::TableSeq *) override { return false; }
38 bool preorder(const IR::MAU::Table *tbl) override {
39 return !tbl->is_a_gateway_table_only();
40 }
41
42 bool preorder(const IR::MAU::Instruction *inst) override {
43 for (unsigned i = 0; i < inst->operands.size(); i++) {
44 auto f = phv.field(inst->operands[i]);
45 if (f) {
46 if (i)
47 reads.insert(f);
48 else
49 writes.insert(f);
50 }
51 }
52
53 return false;
54 }
55 };
56
58 const PhvInfo &phv;
59 explicit PhvDetails(const PhvInfo &p) : phv(p) {}
60
61 void dump(std::ostream &out, const IR::MAU::Table *tbl) const override {
62 out << FlowGraph::viz_node_name(tbl) << " [ shape=record, style=\"filled\","
63 << " fillcolor=cornsilk, label=\""
64 << (tbl->is_a_gateway_table_only() ? tbl->gateway_cond : tbl->name) << "\\l\\l"
65 << std::endl;
66
67 if (!tbl->match_key.empty()) {
68 out << "M:\\l" << std::endl;
69 for (auto m : tbl->match_key) {
70 auto f = phv.field(m->expr);
71 // When match on an error type is used the PHV does not exist
72 BUG_CHECK(
73 f,
74 "PHV details for %s not found. Possibly trying to match on an error type?",
75 m->expr);
76 out << " " << stripThreadPrefix(f->name) << "\\l" << std::endl;
77 }
78 out << "\\l";
79 }
80
81 CollectPhvReadsAndWrites fields(phv);
82 tbl->apply(fields);
83
84 if (!fields.reads.empty()) {
85 out << "R:\\l" << std::endl;
86 for (auto r : fields.reads)
87 out << " " << stripThreadPrefix(r->name) << "\\l" << std::endl;
88 out << "\\l";
89 }
90
91 if (!fields.writes.empty()) {
92 out << "W:\\l" << std::endl;
93 for (auto w : fields.writes)
94 out << " " << stripThreadPrefix(w->name) << "\\l" << std::endl;
95 }
96
97 out << " \"];" << std::endl;
98 }
99 };
100
101 std::ofstream *open_file(gress_t gress, int pipe_id, cstring directory = "graphs"_cs) {
102 auto outdir = BFNContext::get().getOutputDirectory(directory, pipe_id);
103 if (!outdir) return nullptr;
104
105 static int fid = 0;
106 auto filepath = outdir + "/" + std::to_string(fid++) + "_" + "table_flow_graph" + "_" +
107 ::toString(gress) + ".dot";
108
109 return new std::ofstream(filepath);
110 }
111
112 const IR::Node *apply_visitor(const IR::Node *n, const char *) override { return n; }
113
114 Visitor::profile_t init_apply(const IR::Node *root) override {
115 auto rv = Visitor::init_apply(root);
116
118 FindFlowGraphs ffg(graphs);
119 root->apply(ffg);
120
121 for (auto &kv : graphs) {
122 if (kv.second.emptyFlowGraph) continue;
123
124 auto fs = open_file(kv.first, root->to<IR::BFN::Pipe>()->canon_id());
125 kv.second.dump_viz(*fs, new PhvDetails(phv));
126 }
127 return rv;
128 }
129};
130
131#endif /* BF_P4C_PHV_DUMP_TABLE_FLOW_GRAPH_H_ */
static BFNContext & get()
Definition bf-p4c-options.cpp:777
cstring getOutputDirectory(const cstring &suffix=cstring(), int pipe_id=-1)
Definition bf-p4c-options.cpp:795
Computes a table control-flow graph for each gress in the IR.
Definition table_flow_graph.h:384
Definition visitor.h:400
Definition visitor.h:75
Definition cstring.h:85
Definition ordered_map.h:32
Definition ordered_set.h:32
Definition phv_fields.h:1095
Definition dump_table_flow_graph.h:29
Definition dump_table_flow_graph.h:57
Definition dump_table_flow_graph.h:24
Definition table_flow_graph.h:323