19#ifndef BF_P4C_ARCH_INTRINSIC_METADATA_H_
20#define BF_P4C_ARCH_INTRINSIC_METADATA_H_
22#include "backends/tofino/bf-p4c/arch/bridge_metadata.h"
23#include "backends/tofino/bf-p4c/device.h"
24#include "backends/tofino/bf-p4c/midend/type_checker.h"
25#include "frontends/p4/cloner.h"
26#include "frontends/p4/typeChecking/typeChecker.h"
31const IR::ParserState *convertStartStateToNormalState(
const IR::ParserState *state,
34const IR::ParserState *convertStartStateToNormalState(IR::P4Parser *parser,
cstring newName);
36const IR::ParserState *addNewStartState(
cstring name,
cstring nextState);
37void addNewStartState(IR::P4Parser *parser,
cstring name,
cstring nextState);
40 IR::IndexedVector<IR::StatOrDecl> &&statements,
41 const IR::Expression *selectExpression);
43 IR::IndexedVector<IR::StatOrDecl> &&statements,
46const IR::SelectCase *
createSelectCase(
unsigned bitWidth,
unsigned value,
unsigned mask,
47 const IR::ParserState *nextState);
60static void addIngressMetadata(IR::BFN::TnaParser *parser) {
61 auto *p4EntryPointState = convertStartStateToNormalState(parser,
"ingress_p4_entry_point"_cs);
65 const auto bitSkip = Device::pardeSpec().bitIngressPrePacketPaddingSize();
66 auto packetInParam = parser->tnaParams.at(
"pkt"_cs);
68 "skip_to_packet"_cs, {
createAdvanceCall(packetInParam, bitSkip)}, p4EntryPointState->name);
69 parser->states.push_back(skipToPacketState);
73 const auto bitPhase0Size = Device::pardeSpec().bitPhase0Size();
75 "phase0"_cs, {
createAdvanceCall(packetInParam, bitPhase0Size)}, skipToPacketState->name);
76 parser->states.push_back(phase0State);
84 skipToPacketState->name);
85 parser->states.push_back(resubmitState);
90 auto igIntrMd = parser->tnaParams.at(
"ig_intr_md"_cs);
91 IR::Vector<IR::Expression> selectOn = {
92 new IR::Member(
new IR::PathExpression(igIntrMd),
"resubmit_flag"_cs)};
94 "check_resubmit"_cs, {},
95 new IR::SelectExpression(
new IR::ListExpression(selectOn),
98 parser->states.push_back(checkResubmitState);
102 "ingress_metadata"_cs,
105 parser->tnaParams.at(
"ig_intr_md"_cs))},
106 checkResubmitState->name);
107 parser->states.push_back(igMetadataState);
109 addNewStartState(parser,
"ingress_tna_entry_point"_cs, igMetadataState->name);
114static void addEgressMetadata(IR::BFN::TnaParser *parser,
const IR::ParserState *start_i2e_mirrored,
115 const IR::ParserState *start_e2e_mirrored,
116 const IR::ParserState *start_coalesced,
117 const IR::ParserState *start_egress,
118 std::map<cstring, const IR::SelectCase *> selMap) {
119 auto *p4EntryPointState = convertStartStateToNormalState(parser,
"egress_p4_entry_point"_cs);
124 "bridged_metadata"_cs, {},
125 ((start_egress) ?
"start_egress"_cs : p4EntryPointState->name.name));
126 parser->states.push_back(bridgedMetadataState);
130 IR::Vector<IR::Expression> selectOn;
131 IR::Vector<IR::SelectCase> branchTo;
132 if (start_i2e_mirrored || start_e2e_mirrored || start_coalesced)
133 selectOn.push_back(
new IR::Member(
new IR::PathExpression(
new IR::Path(COMPILER_META)),
134 "instance_type"_cs));
135 if (start_i2e_mirrored) {
136 BUG_CHECK(selMap.count(
"start_i2e_mirrored"_cs) != 0,
137 "Couldn't find the start_i2e_mirrored state?");
138 branchTo.push_back(selMap.at(
"start_i2e_mirrored"_cs));
140 if (start_e2e_mirrored) {
141 BUG_CHECK(selMap.count(
"start_e2e_mirrored"_cs) != 0,
142 "Couldn't find the start_e2e_mirrored state?");
143 branchTo.push_back(selMap.at(
"start_e2e_mirrored"_cs));
145 if (start_coalesced) {
146 BUG_CHECK(selMap.count(
"start_coalesced"_cs) != 0,
147 "Couldn't find the start_coalesced state?");
148 branchTo.push_back(selMap.at(
"start_coalesced"_cs));
151 const IR::ParserState *mirroredState =
nullptr;
152 if (branchTo.size()) {
155 new IR::SelectExpression(
new IR::ListExpression(selectOn), branchTo));
159 parser->states.push_back(mirroredState);
168 auto packetInParam = parser->tnaParams.at(
"pkt"_cs);
171 "check_mirrored"_cs, {},
172 new IR::SelectExpression(
new IR::ListExpression(selectOn),
175 parser->states.push_back(checkMirroredState);
180 "egress_metadata"_cs,
184 parser->tnaParams.at(
"eg_intr_md"_cs))},
185 checkMirroredState->name);
186 parser->states.push_back(egMetadataState);
188 addNewStartState(parser,
"egress_tna_entry_point"_cs, egMetadataState->name);
195 bool found_start =
false;
198 IR::ParserState *preorder(IR::ParserState *state)
override {
199 auto anno = state->getAnnotation(
"name"_cs);
200 if (!anno)
return state;
201 auto name = anno->expr.at(0)->to<IR::StringLiteral>();
205 if (name->value ==
".$start") {
206 LOG1(
"Found p4c added start state for @packet_entry");
212 IR::BFN::TnaParser *postorder(IR::BFN::TnaParser *parser)
override {
214 LOG1(
"Renaming p4c generated start state for @packet_entry");
215 convertStartStateToNormalState(parser,
"old_p4_start_point_to_be_removed"_cs);
224 const IR::ParserState *start_i2e_mirrored =
nullptr;
225 const IR::ParserState *start_e2e_mirrored =
nullptr;
226 const IR::ParserState *start_coalesced =
nullptr;
227 const IR::ParserState *start_egress =
nullptr;
231 std::map<cstring, const IR::SelectCase *> selectCaseMap;
237 IR::ParserState *preorder(IR::ParserState *state)
override {
238 auto anno = state->getAnnotation(
"packet_entry"_cs);
239 if (!anno)
return state;
240 anno = state->getAnnotation(
"name"_cs);
241 auto name = anno->expr.at(0)->to<IR::StringLiteral>();
242 if (name->value ==
".start_i2e_mirrored") {
243 start_i2e_mirrored = state;
244 }
else if (name->value ==
".start_e2e_mirrored") {
245 start_e2e_mirrored = state;
246 }
else if (name->value ==
".start_coalesced") {
247 start_coalesced = state;
248 }
else if (name->value ==
".start_egress") {
249 start_egress = state;
255 IR::ParserState *postorder(IR::ParserState *state)
override {
256 auto anno = state->getAnnotation(
"name"_cs);
257 if (!anno)
return state;
258 auto name = anno->expr.at(0)->to<IR::StringLiteral>();
259 if (name->value ==
".start") {
260 LOG1(
"found start state ");
269 p4c_start = state->name;
270 state->name = IR::ParserState::start;
272 }
else if (name->value ==
".$start") {
273 auto selExpr = state->selectExpression->to<IR::SelectExpression>();
274 BUG_CHECK(selExpr !=
nullptr,
"Couldn't find the select expression?");
275 for (
auto c : selExpr->selectCases) {
276 if (c->state->path->name ==
"start_i2e_mirrored") {
277 selectCaseMap.emplace(
"start_i2e_mirrored"_cs, c);
278 }
else if (c->state->path->name ==
"start_e2e_mirrored") {
279 selectCaseMap.emplace(
"start_e2e_mirrored"_cs, c);
280 }
else if (c->state->path->name ==
"start_coalesced") {
281 selectCaseMap.emplace(
"start_coalesced"_cs, c);
282 }
else if (c->state->path->name ==
"start_egress") {
283 selectCaseMap.emplace(
"start_egress"_cs, c);
292 IR::Path *postorder(IR::Path *path)
override {
293 if (path->name.name == p4c_start) path->name = IR::ParserState::start;
297 IR::BFN::TnaParser *postorder(IR::BFN::TnaParser *parser)
override {
298 if (parser->thread == INGRESS)
299 addIngressMetadata(parser);
301 addEgressMetadata(parser, start_i2e_mirrored, start_e2e_mirrored, start_coalesced,
302 start_egress, selectCaseMap);
310 setName(
"AddIntrinsicMetadata");
Definition intrinsic_metadata.h:194
Definition typeChecker.h:32
Definition ir/pass_manager.h:40
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Definition typeChecker.h:55
Definition source_file.h:131
size_t bitResubmitSize() const
Definition parde_spec.h:395
The namespace encapsulating Barefoot/Intel-specific stuff.
Definition add_t2na_meta.cpp:21
const IR::Statement * createSetMetadata(cstring header, cstring field, int bitWidth, int constant)
Definition intrinsic_metadata.cpp:119
const IR::Statement * createExtractCall(cstring pkt, cstring type, cstring hdr)
Definition intrinsic_metadata.cpp:150
const IR::ParserState * createGeneratedParserState(cstring name, IR::IndexedVector< IR::StatOrDecl > &&statements, const IR::Expression *selectExpression)
Definition intrinsic_metadata.cpp:81
const IR::Statement * createAdvanceCall(cstring pkt, int bits)
Definition intrinsic_metadata.cpp:99
const IR::Expression * createLookaheadExpr(cstring pkt, int bits)
Definition intrinsic_metadata.cpp:179
const IR::Statement * createSetValid(const Util::SourceInfo &si, cstring header, cstring field)
Definition intrinsic_metadata.cpp:141
const IR::SelectCase * createSelectCase(unsigned bitWidth, unsigned value, unsigned mask, const IR::ParserState *nextState)
Definition intrinsic_metadata.cpp:109