17#ifndef BACKENDS_DPDK_DPDKARCH_H_
18#define BACKENDS_DPDK_DPDKARCH_H_
21#include "dpdkProgramStructure.h"
23#include "frontends/common/resolveReferences/resolveReferences.h"
24#include "frontends/p4/evaluator/evaluator.h"
25#include "frontends/p4/sideEffects.h"
26#include "frontends/p4/typeMap.h"
28#include "lib/ordered_map.h"
29#include "midend/flattenInterfaceStructs.h"
30#include "midend/removeLeftSlices.h"
37bool isSimpleExpression(
const IR::Expression *e);
38bool isNonConstantSimpleExpression(
const IR::Expression *e);
41using UserMeta = std::set<cstring>;
43class CollectMetadataHeaderInfo;
61 const IR::Type_Control *rewriteControlType(
const IR::Type_Control *,
cstring);
62 const IR::Type_Parser *rewriteParserType(
const IR::Type_Parser *,
cstring);
63 const IR::Type_Control *rewriteDeparserType(
const IR::Type_Control *,
cstring);
64 const IR::Node *postorder(IR::Type_Control *c)
override;
65 const IR::Node *postorder(IR::Type_Parser *p)
override;
66 const IR::Node *preorder(IR::Member *m)
override;
67 const IR::Node *preorder(IR::PathExpression *pe)
override;
71 : refMap(refMap), structure(structure) {
72 CHECK_NULL(structure);
110 std::unordered_map<const IR::P4Program *, IR::IndexedVector<IR::Node>> newHeaderMap;
111 std::unordered_map<const IR::P4Parser *, IR::IndexedVector<IR::Declaration>> newLocalVarMap;
112 std::unordered_map<const IR::AssignmentStatement *, IR::IndexedVector<IR::StatOrDecl>>
116 void insertHeader(
const IR::P4Program *p,
const IR::Type_Header *h) {
117 if (newHeaderMap.count(p)) {
118 newHeaderMap.at(p).push_back(h);
122 LOG5(
"Program: " << dbp(p));
123 LOG2(
"Adding new header:" << std::endl <<
" " << h);
126 if (newHeaderMap.count(p)) {
131 void insertVar(
const IR::P4Parser *p,
const IR::Declaration_Variable *v) {
132 if (newLocalVarMap.count(p)) {
133 newLocalVarMap.at(p).push_back(v);
137 LOG5(
"Parser: " << dbp(p));
138 LOG2(
"Adding new local variable:" << std::endl <<
" " << v);
141 if (newLocalVarMap.count(p)) {
146 void insertStatements(
const IR::AssignmentStatement *as,
148 BUG_CHECK(newStatMap.count(as) == 0,
149 "Unexpectedly converting statement %1% multiple times!", as);
150 newStatMap.emplace(as, *vec);
151 LOG5(
"AssignmentStatement: " << dbp(as));
152 LOG2(
"Adding new statements:");
153 for (
auto s : *vec) {
158 if (newStatMap.count(as)) {
174 : refMap(refMap), typeMap(typeMap), repl(repl) {}
175 void postorder(
const IR::AssignmentStatement *statement)
override;
184 : structure(structure), repl(repl) {}
185 const IR::Node *postorder(IR::AssignmentStatement *as)
override;
186 const IR::Node *postorder(IR::Type_Struct *s)
override;
187 const IR::Node *postorder(IR::P4Parser *parser)
override;
192 passes.push_back(
new Collect(refMap, typeMap, &repl));
193 passes.push_back(
new Replace(s, &repl));
205 void pushMetadata(
const IR::Parameter *p);
206 void pushMetadata(
const IR::ParameterList *, std::list<int> indices);
210 bool preorder(
const IR::P4Program *p)
override;
211 bool preorder(
const IR::Type_Struct *s)
override;
222 const IR::Node *preorder(IR::Type_Struct *s)
override;
234 const IR::Node *preorder(IR::Type_Struct *s)
override;
247 CHECK_NULL(structure);
249 const IR::Node *preorder(IR::Type_StructLike *st)
override;
250 const IR::Node *preorder(IR::Member *m)
override;
260 : typeMap(typeMap), refMap(refMap), structure(structure) {
261 CHECK_NULL(structure);
289 std::map<const IR::Node *, IR::IndexedVector<IR::Declaration> *> decl_map;
293 void collect(
const IR::P4Control *control,
const IR::P4Parser *parser,
294 const IR::Declaration *decl) {
297 auto res = decl_map.find(parser);
298 if (res != decl_map.end()) {
302 decl_map.emplace(parser, decls);
304 }
else if (control) {
305 auto res = decl_map.find(control);
306 if (res != decl_map.end()) {
310 decl_map.emplace(control, decls);
313 BUG_CHECK(decls !=
nullptr,
"decls cannot be null");
314 decls->push_back(decl);
317 auto res = decl_map.find(orig);
318 if (res == decl_map.end()) {
321 control->controlLocals.prepend(*res->second);
325 auto res = decl_map.find(orig);
326 if (res == decl_map.end()) {
329 parser->parserLocals.prepend(*res->second);
348 : refMap(refMap), structure(structure) {}
349 const IR::Node *preorder(IR::AssignmentStatement *a)
override;
350 const IR::Node *postorder(IR::P4Control *a)
override;
351 const IR::Node *postorder(IR::P4Parser *a)
override;
369 IR::PathExpression *root;
371 setName(
"ExpressionUnroll");
373 bool preorder(
const IR::Operation_Unary *a)
override;
374 bool preorder(
const IR::Operation_Binary *a)
override;
375 bool preorder(
const IR::MethodCallExpression *a)
override;
376 bool preorder(
const IR::Member *a)
override;
377 bool preorder(
const IR::PathExpression *a)
override;
378 bool preorder(
const IR::Constant *a)
override;
379 bool preorder(
const IR::BoolLiteral *a)
override;
392 setName(
"IfStatementUnroll");
394 const IR::Node *postorder(IR::SwitchStatement *a)
override;
395 const IR::Node *postorder(IR::IfStatement *a)
override;
396 const IR::Node *postorder(IR::P4Control *a)
override;
397 const IR::Node *postorder(IR::P4Parser *a)
override;
410 IR::Expression *root;
411 static bool is_logical(
const IR::Operation_Binary *bin) {
412 if (bin->is<IR::LAnd>() || bin->is<IR::LOr>() || bin->is<IR::Leq>() || bin->is<IR::Equ>() ||
413 bin->is<IR::Neq>() || bin->is<IR::Grt>() || bin->is<IR::Lss>() || bin->is<IR::Geq>() ||
421 visitDagOnce =
false;
423 bool preorder(
const IR::Operation_Unary *a)
override;
424 bool preorder(
const IR::Operation_Binary *a)
override;
425 bool preorder(
const IR::MethodCallExpression *a)
override;
426 bool preorder(
const IR::Member *a)
override;
427 bool preorder(
const IR::PathExpression *a)
override;
428 bool preorder(
const IR::Constant *a)
override;
429 bool preorder(
const IR::BoolLiteral *a)
override;
441 const IR::Node *postorder(IR::AssignmentStatement *a)
override;
442 const IR::Node *postorder(IR::P4Control *a)
override;
443 const IR::Node *postorder(IR::P4Parser *a)
override;
458 for (
auto d : *locals) {
459 if (
auto dv = d->to<IR::Declaration_Variable>()) {
460 const cstring name = refMap->
newName(prefix +
"_" + dv->name.name);
461 localsMap.emplace(dv, name);
462 }
else if (!d->is<IR::P4Action>() && !d->is<IR::P4Table>() &&
463 !d->is<IR::Declaration_Instance>()) {
464 BUG(
"%1%: Unhandled declaration type", d);
472 : refMap(refMap), typeMap(typeMap), structure(structure) {}
473 const IR::Node *preorder(IR::P4Program *p)
override;
474 const IR::Node *postorder(IR::Type_Struct *s)
override;
475 const IR::Node *postorder(IR::Member *m)
override;
476 const IR::Node *postorder(IR::PathExpression *path)
override;
477 const IR::Node *postorder(IR::P4Control *c)
override;
478 const IR::Node *postorder(IR::P4Parser *p)
override;
497 : typeMap(typeMap), refMap(refMap), structure(structure) {}
498 const IR::Node *postorder(IR::P4Action *a)
override;
499 const IR::Node *postorder(IR::P4Program *s)
override;
500 const IR::Node *preorder(IR::PathExpression *path)
override;
501 const IR::Node *preorder(IR::MethodCallExpression *)
override;
517 : typeMap(typeMap), refMap(refMap), structure(structure) {}
518 void postorder(
const IR::P4Table *t)
override;
530 cstring createTemporary(
const IR::Type *type);
532 const IR::Expression *expression);
536 : typeMap(typeMap), refMap(refMap) {}
537 const IR::Node *preorder(IR::Mux *expression)
override;
538 const IR::Node *postorder(IR::P4Parser *parser)
override;
539 const IR::Node *postorder(IR::Function *function)
override;
540 const IR::Node *postorder(IR::P4Control *control)
override;
541 const IR::Node *postorder(IR::P4Action *action)
override;
542 const IR::Node *postorder(IR::AssignmentStatement *statement)
override;
555 std::vector<cstring> *csum_vec;
560 std::vector<cstring> *csum_vec)
561 : typeMap(typeMap), structure(structure), csum_vec(csum_vec) {}
562 bool preorder(
const IR::Declaration_Instance *d)
override {
563 auto type = typeMap->getType(d,
true);
564 if (
auto extn = type->to<IR::Type_Extern>()) {
565 if (extn->name ==
"InternetChecksum") {
566 std::ostringstream s;
567 s <<
"state_" << index++;
568 csum_vec->push_back(s.str());
569 structure->csum_map.emplace(d, s.str());
581 std::vector<cstring> *csum_vec;
585 std::vector<cstring> *csum_vec)
586 : structure(structure), csum_vec(csum_vec) {}
588 const IR::Node *postorder(IR::P4Program *p)
override {
590 bool inserted =
false;
591 for (
auto obj : p->objects) {
592 if (obj->to<IR::Type_Header>() && !inserted) {
594 if (csum_vec->size() > 0) {
596 for (
auto fld : *csum_vec) {
598 new IR::StructField(
IR::ID(fld), IR::Type::Bits::get(16,
false)));
600 new_objs->push_back(
new IR::Type_Header(
IR::ID(
"cksum_state_t"), *fields));
603 new_objs->push_back(obj);
605 p->objects = *new_objs;
609 const IR::Node *postorder(IR::Type_Struct *s)
override {
610 if (s->name.name == structure->header_type) {
611 if (structure->csum_map.size() > 0)
612 s->fields.push_back(
new IR::StructField(
613 IR::ID(
"cksum_state"),
new IR::Type_Name(
IR::ID(
"cksum_state_t"))));
620 std::vector<cstring> csum_vec;
636 bool preorder(
const IR::Declaration_Instance *d)
override {
637 if (
auto type = d->type->to<IR::Type_Name>()) {
638 auto externTypeName = type->path->name.name;
639 if (externTypeName ==
"DirectMeter") {
640 if (d->arguments->size() != 1) {
642 "%1%: expected type of meter as the only argument", d);
645 if (d->arguments->at(0)->expression->to<IR::Constant>()->asUnsigned() == 0)
646 warn(ErrorType::WARN_UNSUPPORTED,
647 "%1%: Packet metering is not supported."
648 " Falling back to byte metering.",
655 structure->externDecls.push_back(d);
656 }
else if (
auto type = d->type->to<IR::Type_Specialized>()) {
657 auto externTypeName = type->baseType->path->name.name;
658 if (externTypeName ==
"Meter") {
659 if (d->arguments->size() != 2) {
661 "%1%: expected number of meters and type of meter as arguments", d);
664 if (d->arguments->at(1)->expression->to<IR::Constant>()->asUnsigned() == 0)
665 warn(ErrorType::WARN_UNSUPPORTED,
666 "%1%: Packet metering is not supported."
667 " Falling back to byte metering.",
670 }
else if (externTypeName ==
"Counter") {
671 if (d->arguments->size() != 2) {
673 "%1%: expected number of counters and type of counter as arguments",
676 }
else if (externTypeName ==
"DirectCounter") {
677 if (d->arguments->size() != 1) {
679 "%1%: expected type of counter as the only argument", d);
681 }
else if (externTypeName ==
"Register") {
682 if (d->arguments->size() != 1 && d->arguments->size() != 2) {
684 "%1%: expected size and optionally init_val as arguments", d);
686 }
else if (externTypeName ==
"Hash") {
687 if (d->arguments->size() != 1) {
689 "%1%: expected hash algorithm as the only argument", d);
695 structure->externDecls.push_back(d);
707 const IR::Node *postorder(IR::LAnd *land) {
708 if (
auto land2 = land->left->to<IR::LAnd>()) {
709 auto sub =
new IR::LAnd(land2->right, land->right);
710 return new IR::LAnd(land2->left, sub);
711 }
else if (!land->left->is<IR::LOr>() && !land->left->is<IR::Equ>() &&
712 !land->left->is<IR::Neq>() && !land->left->is<IR::Leq>() &&
713 !land->left->is<IR::Geq>() && !land->left->is<IR::Lss>() &&
714 !land->left->is<IR::Grt>() && !land->left->is<IR::MethodCallExpression>() &&
715 !land->left->is<IR::PathExpression>() && !land->left->is<IR::Member>()) {
716 BUG(
"Logical Expression Unroll pass failed");
720 const IR::Node *postorder(IR::LOr *lor) {
721 if (
auto lor2 = lor->left->to<IR::LOr>()) {
722 auto sub =
new IR::LOr(lor2->right, lor->right);
723 return new IR::LOr(lor2->left, sub);
724 }
else if (!lor->left->is<IR::LAnd>() && !lor->left->is<IR::Equ>() &&
725 !lor->left->is<IR::Neq>() && !lor->left->is<IR::Lss>() &&
726 !lor->left->is<IR::Grt>() && !lor->left->is<IR::MethodCallExpression>() &&
727 !lor->left->is<IR::PathExpression>() && !lor->left->is<IR::Member>()) {
728 BUG(
"Logical Expression Unroll pass failed");
740 if (n->
is<IR::Equ>() || n->
is<IR::Neq>() || n->
is<IR::Lss>() || n->
is<IR::Grt>() ||
741 n->
is<IR::Geq>() || n->
is<IR::Leq>() || n->
is<IR::MethodCallExpression>() ||
742 n->
is<IR::PathExpression>() || n->
is<IR::Member>()) {
744 }
else if (!n->
is<IR::LAnd>() && !n->
is<IR::LOr>()) {
745 BUG(
"Logical Expression Unroll pass failed");
752 const IR::Node *postorder(IR::LAnd *land) {
753 if (!is_simple(land->left) && is_simple(land->right)) {
754 return new IR::LAnd(land->right, land->left);
755 }
else if (!is_simple(land->left)) {
756 if (
auto land2 = land->right->to<IR::LAnd>()) {
757 if (is_simple(land2->left)) {
758 auto sub =
new IR::LAnd(land->left, land2->right);
759 return new IR::LAnd(land2->left, sub);
765 const IR::Node *postorder(IR::LOr *lor) {
766 if (!is_simple(lor->left) && is_simple(lor->right)) {
767 return new IR::LOr(lor->right, lor->left);
768 }
else if (!is_simple(lor->left)) {
769 if (
auto lor2 = lor->right->to<IR::LOr>()) {
770 if (is_simple(lor2->left)) {
771 auto sub =
new IR::LOr(lor->left, lor2->right);
772 return new IR::LOr(lor2->left, sub);
803 setName(
"CollectTableInfo");
805 bool preorder(
const IR::Key *key)
override;
816 int offsetInMetadata;
822 int numExistingMetaFields;
826 std::vector<struct keyElementInfo *> elements;
832 bool metaCopyNeeded =
false;
838 setName(
"CopyMatchKeysToSingleStruct");
841 const IR::Node *preorder(IR::Key *key)
override;
842 const IR::Node *postorder(IR::KeyElement *element)
override;
843 const IR::Node *doStatement(
const IR::Statement *statement,
const IR::Expression *expression,
845 struct keyInfo *getKeyInfo(IR::Key *keys);
846 cstring getTableKeyName(
const IR::Expression *e);
847 int getFieldSizeBits(
const IR::Type *field_type);
848 bool isLearnerTable(
const IR::P4Table *t);
855 std::map<cstring, std::vector<std::tuple<cstring, IR::Constant *>>> actionCaseMap;
859 void addToSwitchMap(
cstring actionName,
cstring switchExprTmp, IR::Constant *caseLabelValue) {
860 actionCaseMap[actionName].push_back(std::make_tuple(switchExprTmp, caseLabelValue));
863 const IR::Node *setSwitchVarInAction(IR::P4Action *action) {
864 if (actionCaseMap.count(action->name.name)) {
867 auto acm = actionCaseMap[action->name.name];
868 auto body =
new IR::BlockStatement(action->body->srcInfo);
869 for (
auto pair : acm) {
870 auto assn =
new IR::AssignmentStatement(
871 new IR::PathExpression(
IR::ID(get<0>(pair))), get<1>(pair));
872 body->push_back(assn);
874 for (
auto s : action->body->components) body->push_back(s);
876 actionCaseMap.erase(action->name.name);
890 enum class TableImplementation { DEFAULT, ACTION_PROFILE, ACTION_SELECTOR };
895 TableImplementation implementation;
896 std::set<cstring> match_tables;
897 std::map<cstring, cstring> group_tables;
898 std::map<cstring, cstring> member_tables;
899 std::map<cstring, cstring> member_ids;
900 std::map<cstring, cstring> group_ids;
904 : refMap(refMap), typeMap(typeMap), structure(structure), sw(sw) {
905 implementation = TableImplementation::DEFAULT;
908 const IR::Node *postorder(IR::MethodCallStatement *)
override;
909 const IR::Node *postorder(IR::IfStatement *)
override;
910 const IR::Node *postorder(IR::SwitchStatement *)
override;
911 const IR::Node *postorder(IR::P4Control *)
override;
913 const IR::P4Table * );
915 const IR::P4Table *create_member_table(
const IR::P4Table *,
cstring,
cstring);
933 implementation = TableImplementation::ACTION_SELECTOR;
935 const IR::Node *postorder(IR::P4Table *tbl)
override;
948 implementation = TableImplementation::ACTION_PROFILE;
950 const IR::Node *postorder(IR::P4Table *tbl)
override;
977 const IR::Node *postorder(IR::P4Action *action) {
return sw.setSwitchVarInAction(action); }
1012 bool methodCallFound;
1013 int getTableSize(
const IR::P4Table *tbl);
1014 bool ifMethodFound(
const IR::P4Action *a,
cstring method,
1015 cstring instancename = cstring::empty);
1022 : refMap(refMap), typeMap(typeMap), structure(structure) {
1023 setName(
"CollectDirectCounterMeter");
1024 visitDagOnce =
false;
1025 method = cstring::empty;
1026 instancename = cstring::empty;
1027 oneInstance = cstring::empty;
1028 methodCallFound =
false;
1031 bool preorder(
const IR::MethodCallStatement *mcs)
override;
1032 bool preorder(
const IR::AssignmentStatement *assn)
override;
1033 bool preorder(
const IR::P4Action *a)
override;
1034 bool preorder(
const IR::P4Table *t)
override;
1046 : refMap(refMap), typeMap(typeMap), structure(structure) {}
1048 void postorder(
const IR::AssignmentStatement *)
override;
1049 void postorder(
const IR::MethodCallStatement *)
override;
1060 : refMap(refMap), typeMap(typeMap), structure(structure) {}
1062 void postorder(
const IR::P4Table *t)
override;
1063 void postorder(
const IR::MethodCallStatement *)
override;
1074 : refMap(refMap), typeMap(typeMap), structure(structure) {}
1076 void postorder(
const IR::MethodCallStatement *)
override;
1077 cstring getDefActionName(
const IR::P4Table *t) {
1078 auto act = t->getDefaultAction();
1079 BUG_CHECK(act !=
nullptr,
"%1%: default action does not exist", t);
1080 if (
auto mc = act->to<IR::MethodCallExpression>()) {
1081 auto method = mc->method->to<IR::PathExpression>();
1082 return method->path->name;
1093 void isValidOperandSize(
const IR::Expression *e) {
1094 if (
auto t = e->type->to<IR::Type_Bits>()) {
1096 ::P4::error(ErrorType::ERR_UNSUPPORTED_ON_TARGET,
"Unsupported bitwidth %1% in %2%",
1097 t->width_bits(), e);
1103 void postorder(
const IR::Operation_Binary *binop)
override {
1104 if (binop->is<IR::BOr>() || binop->is<IR::BAnd>() || binop->is<IR::BXor>() ||
1105 binop->is<IR::Equ>() || binop->is<IR::Neq>()) {
1106 if (
auto src1Type = binop->left->type->to<IR::Type_Bits>()) {
1107 if (src1Type->width_bits() == 128)
return;
1110 isValidOperandSize(binop->left);
1111 isValidOperandSize(binop->right);
1115 void postorder(
const IR::Operation_Unary *unop)
override {
1116 if (unop->is<IR::Cast>())
return;
1117 if (unop->is<IR::Cmpl>()) {
1118 if (
auto src1Type = unop->expr->type->to<IR::Type_Bits>()) {
1119 if (src1Type->width_bits() == 128)
return;
1122 isValidOperandSize(unop->expr);
1125 void postorder(
const IR::Operation_Ternary *top)
override {
1126 isValidOperandSize(top->e0);
1127 isValidOperandSize(top->e1);
1128 isValidOperandSize(top->e2);
1137 CHECK_NULL(structure);
1139 void postorder(
const IR::Type_Error *
error)
override {
1141 for (
auto err :
error->members) {
1142 if (structure->error_map.count(err->name.name) == 0) {
1143 structure->error_map.emplace(err->name.name,
id++);
1187 bool isHeader(
const IR::Expression *e);
1188 const IR::Node *preorder(IR::AssignmentStatement *as)
override;
1189 const IR::Node *preorder(IR::MethodCallStatement *mcs)
override;
1190 const IR::Node *postorder(IR::Member *m)
override;
1208 bool &is_all_arg_header_fields;
1212 : is_all_arg_header_fields(is_all_arg_header_fields) {}
1213 bool preorder(
const IR::AssignmentStatement *assn)
override {
1214 if (!is_all_arg_header_fields)
return false;
1215 if ((isLargeFieldOperand(assn->left) && !isLargeFieldOperand(assn->right) &&
1216 !isInsideHeader(assn->right)) ||
1217 (isLargeFieldOperand(assn->left) && assn->right->is<IR::Constant>()) ||
1218 (!isLargeFieldOperand(assn->left) && isLargeFieldOperand(assn->right) &&
1219 !isInsideHeader(assn->left))) {
1220 is_all_arg_header_fields &=
false;
1231 bool &is_all_arg_header_fields;
1235 : typeMap(typeMap), is_all_arg_header_fields(is_all_arg_header_fields) {}
1236 bool preorder(
const IR::MethodCallExpression *mce)
override {
1237 if (!is_all_arg_header_fields)
return false;
1238 if (
auto *m = mce->method->to<IR::Member>()) {
1239 if (
auto *type = typeMap->getType(m->expr)->to<IR::Type_Extern>()) {
1240 if (type->name ==
"InternetChecksum") {
1241 if (m->member ==
"add" || m->member ==
"subtract") {
1242 for (
auto arg : *mce->arguments) {
1243 if (
auto se = arg->expression->to<IR::StructExpression>()) {
1244 for (
auto c : se->components) {
1245 if (
auto m0 = c->expression->to<IR::Member>()) {
1246 if (!typeMap->getType(m0->expr,
true)
1247 ->is<IR::Type_Header>()) {
1248 is_all_arg_header_fields =
false;
1252 is_all_arg_header_fields =
false;
1256 }
else if (arg->expression->to<IR::Constant>()) {
1257 is_all_arg_header_fields =
false;
1259 }
else if (
auto m = arg->expression->to<IR::Member>()) {
1260 if (!(typeMap->getType(m->expr,
true)->is<IR::Type_Header>() ||
1261 typeMap->getType(m,
true)->is<IR::Type_Header>())) {
1262 is_all_arg_header_fields =
false;
1284 bool &is_all_args_header;
1288 static cstring pseudoHeaderInstanceName;
1289 static cstring pseudoHeaderTypeName;
1291 bool &is_all_args_header)
1292 : refMap(refMap), typeMap(typeMap), is_all_args_header(is_all_args_header) {
1293 pseudoHeaderInstanceName = refMap->
newName(
"dpdk_pseudo_header");
1294 pseudoHeaderTypeName = refMap->
newName(
"dpdk_pseudo_header_t");
1295 (void)this->typeMap;
1299 const IR::Node *preorder(IR::P4Program *program)
override;
1300 const IR::Node *preorder(IR::Type_Struct *st)
override;
1321 bool &is_all_args_header;
1325 static std::vector<std::pair<cstring, const IR::Type *>> pseudoFieldNameType;
1327 bool &is_all_args_header)
1328 : refMap(refMap), typeMap(typeMap), is_all_args_header(is_all_args_header) {}
1329 std::pair<IR::AssignmentStatement *, IR::Member *> addAssignmentStmt(
const IR::Expression *ne);
1331 const IR::Node *postorder(IR::P4Program *p)
override {
1332 if (newStructTypes.size() > 0) {
1334 allTypeDecls.append(newStructTypes);
1335 allTypeDecls.append(p->objects);
1336 p->objects = allTypeDecls;
1340 const IR::Node *postorder(IR::MethodCallStatement *statement)
override;
1341 const IR::Node *postorder(IR::AssignmentStatement *statement)
override;
1349 bool &is_all_args_header;
1353 bool &is_all_args_header)
1354 : refMap(refMap), typeMap(typeMap), is_all_args_header(is_all_args_header) {
1355 (void)this->typeMap;
1358 const IR::Node *preorder(IR::Type_Header *h)
override;
1364 bool &is_all_args_header;
1368 bool &is_all_args_header_fields)
1369 : refMap(refMap), typeMap(typeMap), is_all_args_header(is_all_args_header_fields) {
1399 passes.push_back(evaluator);
1400 passes.push_back(
new VisitFunctor([evaluator, parseDpdk]() {
1401 auto toplevel = evaluator->getToplevelBlock();
1402 auto main = toplevel->getMain();
1403 if (main ==
nullptr) {
1405 "Could not locate top-level block; is there a %1% module?",
1406 IR::P4Program::main);
1409 main->apply(*parseDpdk);
1421 const IR::Node *preorder(IR::Type_Struct *s)
override;
1422 const IR::Node *postorder(IR::P4Control *c)
override;
1423 const IR::Node *postorder(IR::P4Program *p)
override;
1424 const IR::Node *postorder(IR::P4Parser *c)
override;
1434 : refMap(refMap), typeMap(typeMap) {}
1435 const IR::Node *postorder(IR::P4Parser *c)
override;
1436 const IR::Node *preorder(IR::PathExpression *path)
override;
1437 static const IR::Type_Struct *metadataStrct;
1438 static std::map<cstring, const IR::Type *> fieldNameType;
1463 bool &is_ipsec_used;
1472 : is_ipsec_used(is_ipsec_used),
1473 sa_id_width(sa_id_width),
1476 structure(structure) {}
1477 bool preorder(
const IR::MethodCallStatement *mcs)
override {
1480 if (a->originalExternType->getName().name ==
"ipsec_accelerator") {
1481 if (structure->
isPSA()) {
1482 ::P4::error(ErrorType::ERR_MODEL,
"%1% is not available for PSA programs",
1483 a->originalExternType->getName().name);
1486 if (a->method->getName().name ==
"enable") {
1487 is_ipsec_used =
true;
1488 }
else if (a->method->getName().name ==
"set_sa_index") {
1489 auto typeArgs = a->expr->typeArguments;
1490 if (typeArgs->size() != 1) {
1492 "Unexpected number of type arguments for %1%", a->method->name);
1495 auto width = typeArgs->at(0);
1496 if (!width->is<IR::Type_Bits>()) {
1497 ::P4::error(ErrorType::ERR_MODEL,
"Unexpected width type %1% for sa_index",
1501 sa_id_width = width->to<IR::Type_Bits>()->width_bits();
1517 bool &is_ipsec_used;
1519 cstring newHeaderName =
"platform_hdr_t"_cs;
1520 IR::Type_Header *ipsecHeader =
nullptr;
1521 std::vector<cstring> registerInstanceNames = {
1522 "ipsec_port_out_inbound"_cs,
"ipsec_port_out_outbound"_cs,
"ipsec_port_in_inbound"_cs,
1523 "ipsec_port_in_outbound"_cs};
1527 bool &is_ipsec_used,
int &sa_id_width)
1529 structure(structure),
1530 is_ipsec_used(is_ipsec_used),
1531 sa_id_width(sa_id_width) {
1532 setName(
"InsertReqDeclForIPSec");
1535 const IR::Node *preorder(IR::P4Program *program)
override;
1536 const IR::Node *preorder(IR::Type_Struct *s)
override;
1537 const IR::Node *preorder(IR::P4Control *c)
override;
1545 bool is_ipsec_used =
false;
1546 int sa_id_width = 32;
1550 : refMap(refMap), typeMap(typeMap), structure(structure) {
1552 new CollectIPSecInfo(is_ipsec_used, sa_id_width, refMap, typeMap, structure));
Definition typeChecker.h:32
Definition dpdkArch.h:705
Definition dpdkArch.h:1052
Definition dpdkArch.h:1002
Definition dpdkArch.h:1132
Definition dpdkArch.h:631
Definition dpdkArch.h:1462
Definition dpdkArch.h:552
Definition dpdkArch.h:1444
Definition dpdkArch.h:451
Definition dpdkArch.h:1393
Definition dpdkArch.h:1428
Definition dpdkArch.h:798
bool preorder(const IR::Key *key) override
Definition dpdkArch.cpp:647
Definition dpdkArch.h:981
Definition dpdkArch.h:435
Definition dpdkArch.h:619
Definition dpdkArch.h:785
Definition dpdkArch.h:167
Definition dpdkArch.h:178
Definition dpdkArch.h:109
Definition dpdkArch.h:829
Definition dpdkArch.h:288
Definition dpdkArch.h:510
void postorder(const IR::P4Table *t) override
Definition dpdkArch.cpp:1228
Definition dpdkArch.h:524
Definition dpdkArch.h:1383
Definition dpdkArch.h:1388
Definition dpdkArch.h:363
This pass checks whether an assignment statement has large operands (>64-bit).
Definition dpdkArch.h:1207
Definition dpdkArch.h:385
Definition dpdkArch.h:217
Definition dpdkArch.h:1514
IR::IndexedVector< IR::StatOrDecl > * addRegDeclInstance(std::vector< cstring > portRegs)
Create and add register declaration instance to program.
Definition dpdkArch.cpp:3225
Definition dpdkArch.h:404
bool preorder(const IR::Operation_Unary *a) override
Definition dpdkArch.cpp:910
Definition dpdkArch.h:489
Definition dpdkArch.h:943
Definition dpdkArch.h:928
Definition dpdkArch.h:885
IR::Expression * initializeMemberAndGroupId(cstring tableName, IR::IndexedVector< IR::StatOrDecl > *decls)
Definition dpdkArch.cpp:2135
std::tuple< const IR::P4Table *, cstring, cstring > create_match_table(const IR::P4Table *)
Definition dpdkArch.cpp:1785
Definition dpdkArch.h:340
Definition dpdkArch.h:738
Definition dpdkArch.h:851
Definition dpdkArch.h:972
Definition dpdkArch.h:1066
Definition dpdkArch.h:1037
Definition dpdkArch.h:1090
Definition removeLeftSlices.h:35
Definition evaluator.h:115
Definition methodInstance.h:168
Definition flattenInterfaceStructs.h:249
Definition sideEffects.h:295
static MethodInstance * resolve(const IR::MethodCallExpression *mce, const DeclarationLookup *refMap, TypeMap *typeMap, bool useExpressionType=false, const Visitor::Context *ctxt=nullptr, bool incomplete=false)
Definition methodInstance.cpp:27
Definition dpdkProgramStructure.h:126
Definition ir/pass_manager.h:40
Definition ir/pass_manager.h:145
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
cstring newName(std::string_view base) override
Generate a name from base that fresh for the program.
Definition referenceMap.cpp:96
Definition resolveReferences.h:123
Definition typeChecker.h:55
Definition typeChecker.h:483
Definition source_file.h:125
Definition ir/pass_manager.h:184
Definition ordered_map.h:32
Definition dpdk/backend.cpp:37
void expressionUnrollSanityCheck(const IR::Expression *e)
Definition dpdkArch.cpp:47
Definition dpdkArch.h:815
Definition dpdkArch.h:820
const int dpdk_max_operand_size
Maximum operand size for unary, binary and ternary operations.
Definition dpdk/constants.h:65
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:51
Definition dpdkArch.h:253
Definition dpdkArch.h:108
Definition dpdkArch.h:1541
Definition dpdkArch.h:278
Collect information related to P4 programs targeting dpdk.
Definition dpdkProgramStructure.h:16
bool isPSA(void)
Predicate that states whether architecture is PSA or not.
Definition dpdkProgramStructure.h:96
bool is() const noexcept
Definition rtti.h:216