P4C
The P4 Compiler
Loading...
Searching...
No Matches
allocate_parser_checksum.h
1
19#ifndef BACKENDS_TOFINO_BF_P4C_PARDE_ALLOCATE_PARSER_CHECKSUM_H_
20#define BACKENDS_TOFINO_BF_P4C_PARDE_ALLOCATE_PARSER_CHECKSUM_H_
21
22#include "bf-p4c/logging/pass_manager.h"
23#include "bf-p4c/parde/clot/clot_info.h"
24#include "bf-p4c/parde/parser_info.h"
25#include "ir/ir.h"
26#include "lib/cstring.h"
27#include "parde_visitor.h"
28
33 explicit CollectParserChecksums(const CollectParserInfo &parser_info)
34 : parser_info(parser_info) {}
35
36 const CollectParserInfo &parser_info;
37
39
41
43
45
46 ordered_map<const IR::BFN::Parser *,
48 decl_name_to_prims;
49
50 ordered_map<const IR::BFN::Parser *,
52 decl_name_to_states;
53
55 state_to_prims;
56
58 prim_to_state;
59
60 profile_t init_apply(const IR::Node *root) override {
61 parser_to_decl_names.clear();
62 parser_to_verifies.clear();
63 parser_to_residuals.clear();
64 parser_to_clots.clear();
65 decl_name_to_prims.clear();
66 decl_name_to_states.clear();
67 state_to_prims.clear();
68 prim_to_state.clear();
69 return Inspector::init_apply(root);
70 }
71 bool preorder(const IR::BFN::Parser *parser) override {
72 auto sorted_states = parser_info.graph(parser).topological_sort();
73
74 for (auto state : sorted_states)
75 for (auto stmt : state->statements)
76 if (auto csum = stmt->to<IR::BFN::ParserChecksumPrimitive>())
77 visit(parser, state, csum);
78
79 return false;
80 }
81
82 void visit(const IR::BFN::Parser *parser, const IR::BFN::ParserState *state,
83 const IR::BFN::ParserChecksumPrimitive *csum) {
84 parser_to_decl_names[parser].insert(csum->declName);
85 prim_to_state[csum] = state;
86 state_to_prims[state].push_back(csum);
87 decl_name_to_states[parser][csum->declName].insert(state);
88 decl_name_to_prims[parser][csum->declName].push_back(csum);
89 }
90
91 bool is_verification(const IR::BFN::Parser *parser, cstring decl) const {
92 for (auto p : decl_name_to_prims.at(parser).at(decl)) {
93 if (!p->is<IR::BFN::ChecksumAdd>() && !p->is<IR::BFN::ChecksumVerify>()) return false;
94 }
95 return true;
96 }
97
98 bool is_residual(const IR::BFN::Parser *parser, cstring decl) const {
99 for (auto p : decl_name_to_prims.at(parser).at(decl)) {
100 if (!p->is<IR::BFN::ChecksumSubtract>() && !p->is<IR::BFN::ChecksumResidualDeposit>())
101 return false;
102 }
103 return true;
104 }
105
106 bool is_clot(const IR::BFN::Parser *parser, cstring decl) const {
107 for (auto p : decl_name_to_prims.at(parser).at(decl)) {
108 if (!p->is<IR::BFN::ChecksumAdd>() && !p->is<IR::BFN::ChecksumDepositToClot>())
109 return false;
110 }
111 return true;
112 }
113
114 IR::BFN::ChecksumMode get_type(const IR::BFN::Parser *parser, cstring name) const {
115 if (is_verification(parser, name))
116 return IR::BFN::ChecksumMode::VERIFY;
117 else if (is_residual(parser, name))
118 return IR::BFN::ChecksumMode::RESIDUAL;
119 else if (is_clot(parser, name))
120 return IR::BFN::ChecksumMode::CLOT;
121 else
122 BUG("Unknown checksum type for %1%", name);
123 }
124
125 void end_apply() override {
126 for (auto &pd : parser_to_decl_names) {
127 for (auto decl : pd.second) {
128 if (is_verification(pd.first, decl))
129 parser_to_verifies[pd.first].insert(decl);
130 else if (is_residual(pd.first, decl))
131 parser_to_residuals[pd.first].insert(decl);
132 else if (is_clot(pd.first, decl))
133 parser_to_clots[pd.first].insert(decl);
134 else
135 error(
136 "Inconsistent use of checksum declaration %1% (it can be used either "
137 "to verify checksum or to calculate residual, but not for both)",
138 decl); // or for CLOTs but that should not be visible to users
139 }
140 }
141 }
142};
143
150 CollectParserInfo parser_info;
151 CollectParserChecksums checksum_info;
152
153 public:
155
157 checksum_id_to_decl;
158
159 ordered_map<const IR::BFN::Parser *,
161 decl_to_start_states;
162
163 ordered_map<const IR::BFN::Parser *,
165 decl_to_end_states;
166
167 AllocateParserChecksums(const PhvInfo &phv, const ClotInfo &clot);
168
169 bool is_start_state(const IR::BFN::Parser *parser, cstring name,
170 const IR::BFN::ParserState *state) const {
171 return decl_to_start_states.at(parser).at(name).count(state);
172 }
173
174 bool is_end_state(const IR::BFN::Parser *parser, cstring name,
175 const IR::BFN::ParserState *state) const {
176 return decl_to_end_states.at(parser).at(name).count(state);
177 }
178
179 IR::BFN::ChecksumMode get_type(const IR::BFN::Parser *parser, cstring name) const {
180 return checksum_info.get_type(parser, name);
181 }
182
183 unsigned get_id(const IR::BFN::Parser *parser, cstring name) const {
184 return decl_to_checksum_id.at(parser).at(name);
185 }
186};
187
188#endif /* BACKENDS_TOFINO_BF_P4C_PARDE_ALLOCATE_PARSER_CHECKSUM_H_ */
Definition allocate_parser_checksum.h:149
Definition clot_info.h:41
Definition backends/tofino/bf-p4c/logging/pass_manager.h:36
Definition node.h:95
Definition cstring.h:85
Definition ordered_map.h:32
Definition phv_fields.h:1095
Definition allocate_parser_checksum.h:32
Definition parde_visitor.h:66
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:51