P4C
The P4 Compiler
Loading...
Searching...
No Matches
table_tree.h
1
19#ifndef BF_P4C_IR_TABLE_TREE_H_
20#define BF_P4C_IR_TABLE_TREE_H_
21
22#include "ir/ir.h"
23#include "lib/hex.h"
24#include "lib/indent.h"
25#include "lib/n4.h"
26#include "lib/ordered_map.h"
27#include "lib/safe_vector.h"
28
29class TableTree {
30 mutable indent_t indent;
31 mutable std::set<const IR::MAU::TableSeq *> done;
32 safe_vector<cstring> name;
33 const IR::MAU::TableSeq *seq;
34 const IR::BFN::Pipe *pipe;
35
36 void print(std::ostream &out, const safe_vector<cstring> &tag,
37 const IR::MAU::TableSeq *s) const {
38 const char *sep = "";
39 out << indent++;
40 for (auto n : tag) {
41 out << sep << n;
42 sep = ", ";
43 }
44 out << ": [" << s->seq_uid << "]";
45 if (done.count(s)) {
46 out << "..." << std::endl;
47 } else {
48 // for large seqs, output depmatrix as a LT matrix with lables
49 bool big = (s->tables.size() > 5);
50 if (big) out << std::endl << indent << " +--" << s->tables[0]->name;
51 for (unsigned i = 1; i < s->tables.size(); ++i) {
52 if (big) out << std::endl << indent << " ";
53 out << ' ';
54 for (unsigned j = 0; j < i; ++j) out << (s->deps(i, j) ? '1' : '0');
55 if (big) out << "+--" << s->tables[i]->name;
56 }
57 out << std::endl;
58 done.insert(s);
59 for (auto tbl : s->tables) print(out, tbl);
60 }
61 --indent;
62 }
63 void print(std::ostream &out, const IR::MAU::Table *tbl) const {
64 ordered_map<const IR::MAU::TableSeq *, safe_vector<cstring>> next;
65 out << indent++;
66 if (tbl->global_id())
67 out << hex(*tbl->global_id()) << ": ";
68 else if (tbl->stage() != -1)
69 out << hex(tbl->stage() * 16) << ": ";
70 out << tbl->name;
71 const char *sep = "(";
72 for (auto &row : tbl->gateway_rows) {
73 out << sep;
74 if (row.first)
75 out << *row.first;
76 else
77 out << "1";
78 if (row.second) out << " => " << row.second;
79 sep = ", ";
80 }
81 out << (*sep == ',' ? ")" : "");
82 if (tbl->layout.match_width_bits || tbl->layout.overhead_bits) {
83 out << "{ " << (tbl->layout.gateway ? "G" : "") << (tbl->layout.ternary ? "T" : "E")
84 << " " << tbl->layout.match_width_bits << "+" << tbl->layout.overhead_bits << ", "
85 << tbl->layout.action_data_bytes;
86 if (!tbl->ways.empty()) {
87 out << " [" << tbl->ways[0].width << 'x' << tbl->ways[0].match_groups;
88 for (auto &way : tbl->ways) out << " " << (way.entries / 1024U) << "K";
89 out << "]";
90 } else {
91 out << " " << (tbl->layout.entries / 1024U) << "K";
92 }
93 out << " }";
94 }
95 auto stage = tbl->get_provided_stage();
96 if (stage >= 0) out << " @stage(" << stage << ")";
97 out << std::endl;
98 for (auto &at : tbl->attached) {
99 if (at->attached->direct) continue;
100 out << indent << at->attached->kind() << " " << at->attached->name << " "
101 << n4(at->attached->size) << std::endl;
102 }
103 for (auto &n : tbl->next) next[n.second].push_back(n.first);
104 for (auto &n : next) print(out, n.second, n.first);
105 --indent;
106 }
107
108 public:
109 TableTree(cstring name, const IR::MAU::TableSeq *seq) : name{name}, seq(seq), pipe(nullptr) {}
110 explicit TableTree(const IR::BFN::Pipe *pipe) : name{}, seq(nullptr), pipe(pipe) {}
111 friend std::ostream &operator<<(std::ostream &out, const TableTree &tt) {
112 tt.indent = indent_t();
113 tt.done.clear();
114 if (tt.pipe) {
115 if (tt.pipe->thread[INGRESS].mau)
116 tt.print(out, {"ingress"_cs}, tt.pipe->thread[INGRESS].mau);
117 if (tt.pipe->thread[EGRESS].mau)
118 tt.print(out, {"egress"_cs}, tt.pipe->thread[EGRESS].mau);
119 if (tt.pipe->ghost_thread.ghost_mau)
120 tt.print(out, {"ghost mau"_cs}, tt.pipe->ghost_thread.ghost_mau);
121 } else if (tt.seq) {
122 tt.print(out, tt.name, tt.seq);
123 }
124 return out;
125 }
126};
127
128#endif /* BF_P4C_IR_TABLE_TREE_H_ */
Definition table_tree.h:29