34 static int id_counter;
35 const bool &long_branch_disabled;
36 std::set<cstring> *errors;
40 bool preorder(
const IR::Expression *)
override {
return false; }
42 bool preorder(
const IR::MAU::Table *tbl)
override {
43 LOG3(
id <<
": DefaultNext::preorder(" << tbl->name <<
") prev=" << DBPrint::Brief
44 << prev_tbls << DBPrint::Reset);
45 if (tbl->is_detached_attached_tbl)
return true;
46 if (tbl->run_before_exit) collect_run_before_exit_table(tbl);
47 for (
auto prev : prev_tbls) {
48 if (possible_nexts.count(prev)) {
51 if (!possible_nexts.at(prev).count(tbl) && long_branch_disabled) {
52 error(ErrorType::ERR_UNSUPPORTED_ON_TARGET,
53 "%1% is applied in multiple "
54 "places, and the next-table information cannot correctly propagate "
55 "through this multiple application",
57 if (errors) errors->insert(prev->externalName());
60 possible_nexts[prev].insert(tbl);
66 void collect_run_before_exit_table(
const IR::MAU::Table *rbe_table) {
67 run_before_exit_tables[rbe_table->gress].push_back(rbe_table);
70 void postorder(
const IR::MAU::Table *tbl)
override {
71 LOG3(
id <<
": DefaultNext::postorder(" << tbl->name <<
")");
72 prev_tbls.insert(tbl);
77 rv->id = ++id_counter;
78 LOG3(
id <<
": DefaultNext::clone -> " << rv->id);
82 void flow_merge(
Visitor &a_)
override {
84 LOG3(
id <<
": DefaultNext::flow_merge <- " << a.id);
85 prev_tbls.insert(a.prev_tbls.begin(), a.prev_tbls.end());
89 prev_tbls = a.prev_tbls;
90 run_before_exit_tables = a.run_before_exit_tables;
95 bool filter_join_point(
const IR::Node *n)
override {
return !n->
is<IR::MAU::TableSeq>(); }
98 LOG3(
"DefaultNext starting");
100 return MauInspector::init_apply(root);
103 bool preorder(
const IR::BFN::Pipe *pipe)
override {
104 LOG5(
TableTree(
"ingress"_cs, pipe->thread[INGRESS].mau)
105 <<
TableTree(
"egress"_cs, pipe->thread[EGRESS].mau)
106 <<
TableTree(
"ghost"_cs, pipe->ghost_thread.ghost_mau));
107 possible_nexts.clear();
112 void postorder(
const IR::BFN::Pipe *)
override {
113 if (long_branch_disabled) {
114 for (
auto prev : prev_tbls) {
115 if (possible_nexts.count(prev)) {
116 error(ErrorType::ERR_UNSUPPORTED_ON_TARGET,
117 "%1% is applied in multiple "
118 "places, and the next-table information cannot correctly propagate "
119 "through this multiple application",
121 if (errors) errors->insert(prev->externalName());
128 std::map<gress_t, std::vector<const IR::MAU::Table *>> run_before_exit_tables;
130 explicit DefaultNext(
const bool &lbd, std::set<cstring> *errs =
nullptr)
131 : long_branch_disabled(lbd),
133 possible_nexts(*
new std::remove_reference<
decltype(possible_nexts)>::type) {
135 visitDagOnce =
false;
136 BackwardsCompatibleBroken =
true;
139 const IR::MAU::Table *next(
const IR::MAU::Table *t)
const {
140 if (possible_nexts.count(t)) {
141 BUG_CHECK(!possible_nexts.at(t).empty(),
"unexpected empty set");
142 return possible_nexts.at(t).front();
148 if (possible_nexts.count(t))
return possible_nexts.at(t);
153 for (
auto &pn : possible_nexts) {
154 if (pn.first->name == name)
return pn.second;
155 if (pn.first->match_table && pn.first->externalName() == name)
return pn.second;
160 const IR::MAU::Table *next_in_thread(
const IR::MAU::Table *t)
const {
161 if (
auto *n = next(t))
162 if (n->gress == t->gress)
return n;
166 UniqueId next_in_thread_uniq_id(
const IR::MAU::Table *t)
const {
167 if (
auto *n = next(t))
168 if (n->gress == t->gress)
return n->unique_id();
172 std::set<UniqueId> possible_next_uniq_id(
const IR::MAU::Table *t)
const {
173 std::set<UniqueId> rv;
174 for (
auto n : possible_next(t))
175 if (n->gress == t->gress) rv.insert(n->unique_id());
176 if (rv.empty()) rv.insert(
UniqueId(
"END"_cs));
181 if (what ==
"$miss" && tbl->next.count(
"$try_next_stage"_cs)) what =
"$try_next_stage"_cs;
182 if (tbl->actions.count(what) && tbl->actions.at(what)->exitAction) {
183 if (run_before_exit_tables.count(tbl->gress) && !tbl->run_before_exit)
184 return {(*run_before_exit_tables.at(tbl->gress).begin())->unique_id()};
188 if (!tbl->next.count(what)) what =
"$default"_cs;
189 if (tbl->next.count(what) && !tbl->next.at(what)->empty())
190 return {tbl->next.at(what)->front()->unique_id()};
191 auto *nt = next_in_thread(tbl);
192 if (nt)
return {nt->unique_id()};
196 bool uses_next_table(
const IR::MAU::Table *)
const override {
return true; }
198 void dbprint(std::ostream &out)
const override {
199 out <<
"DefaultNext:" << IndentCtl::indent;
200 for (
auto &pn : possible_nexts) {
201 out << Log::endl << pn.first <<
": {";
202 const char *sep =
" ";
203 for (
auto el : pn.second) {
207 out << (sep + 1) <<
"}";
209 out << IndentCtl::unindent;
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:51