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"
35bool isSimpleExpression(
const IR::Expression *e);
36bool isNonConstantSimpleExpression(
const IR::Expression *e);
37void expressionUnrollSanityCheck(
const IR::Expression *e);
39using UserMeta = std::set<cstring>;
41class CollectMetadataHeaderInfo;
59 const IR::Type_Control *rewriteControlType(
const IR::Type_Control *,
cstring);
60 const IR::Type_Parser *rewriteParserType(
const IR::Type_Parser *,
cstring);
61 const IR::Type_Control *rewriteDeparserType(
const IR::Type_Control *,
cstring);
62 const IR::Node *postorder(IR::Type_Control *c)
override;
63 const IR::Node *postorder(IR::Type_Parser *p)
override;
64 const IR::Node *preorder(IR::Member *m)
override;
65 const IR::Node *preorder(IR::PathExpression *pe)
override;
69 : refMap(refMap), structure(structure) {
70 CHECK_NULL(structure);
108 std::unordered_map<const IR::P4Program *, IR::IndexedVector<IR::Node>> newHeaderMap;
109 std::unordered_map<const IR::P4Parser *, IR::IndexedVector<IR::Declaration>> newLocalVarMap;
110 std::unordered_map<const IR::AssignmentStatement *, IR::IndexedVector<IR::StatOrDecl>>
114 void insertHeader(
const IR::P4Program *p,
const IR::Type_Header *h) {
115 if (newHeaderMap.count(p)) {
116 newHeaderMap.at(p).push_back(h);
118 newHeaderMap.emplace(p, IR::IndexedVector<IR::Node>(h));
120 LOG5(
"Program: " << dbp(p));
121 LOG2(
"Adding new header:" << std::endl <<
" " << h);
123 IR::IndexedVector<IR::Node> *getHeaders(
const IR::P4Program *p) {
124 if (newHeaderMap.count(p)) {
125 return new IR::IndexedVector<IR::Node>(newHeaderMap.at(p));
129 void insertVar(
const IR::P4Parser *p,
const IR::Declaration_Variable *v) {
130 if (newLocalVarMap.count(p)) {
131 newLocalVarMap.at(p).push_back(v);
133 newLocalVarMap.emplace(p, IR::IndexedVector<IR::Declaration>(v));
135 LOG5(
"Parser: " << dbp(p));
136 LOG2(
"Adding new local variable:" << std::endl <<
" " << v);
138 IR::IndexedVector<IR::Declaration> *getVars(
const IR::P4Parser *p) {
139 if (newLocalVarMap.count(p)) {
140 return new IR::IndexedVector<IR::Declaration>(newLocalVarMap.at(p));
144 void insertStatements(
const IR::AssignmentStatement *as,
145 IR::IndexedVector<IR::StatOrDecl> *vec) {
146 BUG_CHECK(newStatMap.count(as) == 0,
147 "Unexpectedly converting statement %1% multiple times!", as);
148 newStatMap.emplace(as, *vec);
149 LOG5(
"AssignmentStatement: " << dbp(as));
150 LOG2(
"Adding new statements:");
151 for (
auto s : *vec) {
155 IR::IndexedVector<IR::StatOrDecl> *getStatements(
const IR::AssignmentStatement *as) {
156 if (newStatMap.count(as)) {
157 return new IR::IndexedVector<IR::StatOrDecl>(newStatMap.at(as));
172 : refMap(refMap), typeMap(typeMap), repl(repl) {}
173 void postorder(
const IR::AssignmentStatement *statement)
override;
182 : structure(structure), repl(repl) {}
183 const IR::Node *postorder(IR::AssignmentStatement *as)
override;
184 const IR::Node *postorder(IR::Type_Struct *s)
override;
185 const IR::Node *postorder(IR::P4Parser *parser)
override;
190 passes.push_back(
new Collect(refMap, typeMap, &repl));
191 passes.push_back(
new Replace(s, &repl));
203 void pushMetadata(
const IR::Parameter *p);
204 void pushMetadata(
const IR::ParameterList *, std::list<int> indices);
208 bool preorder(
const IR::P4Program *p)
override;
209 bool preorder(
const IR::Type_Struct *s)
override;
220 const IR::Node *preorder(IR::Type_Struct *s)
override;
232 const IR::Node *preorder(IR::Type_Struct *s)
override;
245 CHECK_NULL(structure);
247 const IR::Node *preorder(IR::Type_StructLike *st)
override;
248 const IR::Node *preorder(IR::Member *m)
override;
258 : typeMap(typeMap), refMap(refMap), structure(structure) {
259 CHECK_NULL(structure);
273 const IR::Node *postorder(IR::Type_Struct *st)
override;
287 std::map<const IR::Node *, IR::IndexedVector<IR::Declaration> *> decl_map;
291 void collect(
const IR::P4Control *control,
const IR::P4Parser *parser,
292 const IR::Declaration *decl) {
293 IR::IndexedVector<IR::Declaration> *decls =
nullptr;
295 auto res = decl_map.find(parser);
296 if (res != decl_map.end()) {
299 decls =
new IR::IndexedVector<IR::Declaration>;
300 decl_map.emplace(parser, decls);
302 }
else if (control) {
303 auto res = decl_map.find(control);
304 if (res != decl_map.end()) {
307 decls =
new IR::IndexedVector<IR::Declaration>;
308 decl_map.emplace(control, decls);
311 BUG_CHECK(decls !=
nullptr,
"decls cannot be null");
312 decls->push_back(decl);
314 IR::Node *inject_control(
const IR::Node *orig, IR::P4Control *control) {
315 auto res = decl_map.find(orig);
316 if (res == decl_map.end()) {
319 control->controlLocals.prepend(*res->second);
322 IR::Node *inject_parser(
const IR::Node *orig, IR::P4Parser *parser) {
323 auto res = decl_map.find(orig);
324 if (res == decl_map.end()) {
327 parser->parserLocals.prepend(*res->second);
346 : refMap(refMap), structure(structure) {}
347 const IR::Node *preorder(IR::AssignmentStatement *a)
override;
348 const IR::Node *postorder(IR::P4Control *a)
override;
349 const IR::Node *postorder(IR::P4Parser *a)
override;
365 IR::IndexedVector<IR::StatOrDecl> stmt;
366 IR::IndexedVector<IR::Declaration> decl;
367 IR::PathExpression *root;
369 setName(
"ExpressionUnroll");
371 bool preorder(
const IR::Operation_Unary *a)
override;
372 bool preorder(
const IR::Operation_Binary *a)
override;
373 bool preorder(
const IR::MethodCallExpression *a)
override;
374 bool preorder(
const IR::Member *a)
override;
375 bool preorder(
const IR::PathExpression *a)
override;
376 bool preorder(
const IR::Constant *a)
override;
377 bool preorder(
const IR::BoolLiteral *a)
override;
390 setName(
"IfStatementUnroll");
392 const IR::Node *postorder(IR::SwitchStatement *a)
override;
393 const IR::Node *postorder(IR::IfStatement *a)
override;
394 const IR::Node *postorder(IR::P4Control *a)
override;
395 const IR::Node *postorder(IR::P4Parser *a)
override;
406 IR::IndexedVector<IR::StatOrDecl> stmt;
407 IR::IndexedVector<IR::Declaration> decl;
408 IR::Expression *root;
409 static bool is_logical(
const IR::Operation_Binary *bin) {
410 if (bin->is<IR::LAnd>() || bin->is<IR::LOr>() || bin->is<IR::Leq>() || bin->is<IR::Equ>() ||
411 bin->is<IR::Neq>() || bin->is<IR::Grt>() || bin->is<IR::Lss>() || bin->is<IR::Geq>() ||
419 visitDagOnce =
false;
421 bool preorder(
const IR::Operation_Unary *a)
override;
422 bool preorder(
const IR::Operation_Binary *a)
override;
423 bool preorder(
const IR::MethodCallExpression *a)
override;
424 bool preorder(
const IR::Member *a)
override;
425 bool preorder(
const IR::PathExpression *a)
override;
426 bool preorder(
const IR::Constant *a)
override;
427 bool preorder(
const IR::BoolLiteral *a)
override;
439 const IR::Node *postorder(IR::AssignmentStatement *a)
override;
440 const IR::Node *postorder(IR::P4Control *a)
override;
441 const IR::Node *postorder(IR::P4Parser *a)
override;
455 void insert(
const cstring prefix,
const IR::IndexedVector<IR::Declaration> *locals) {
456 for (
auto d : *locals) {
457 if (
auto dv = d->to<IR::Declaration_Variable>()) {
458 const cstring name = refMap->
newName(prefix +
"_" + dv->name.name);
459 localsMap.emplace(dv, name);
460 }
else if (!d->is<IR::P4Action>() && !d->is<IR::P4Table>() &&
461 !d->is<IR::Declaration_Instance>()) {
462 BUG(
"%1%: Unhandled declaration type", d);
470 : refMap(refMap), typeMap(typeMap), structure(structure) {}
471 const IR::Node *preorder(IR::P4Program *p)
override;
472 const IR::Node *postorder(IR::Type_Struct *s)
override;
473 const IR::Node *postorder(IR::Member *m)
override;
474 const IR::Node *postorder(IR::PathExpression *path)
override;
475 const IR::Node *postorder(IR::P4Control *c)
override;
476 const IR::Node *postorder(IR::P4Parser *p)
override;
495 : typeMap(typeMap), refMap(refMap), structure(structure) {}
496 const IR::Node *postorder(IR::P4Action *a)
override;
497 const IR::Node *postorder(IR::P4Program *s)
override;
498 const IR::Node *preorder(IR::PathExpression *path)
override;
499 const IR::Node *preorder(IR::MethodCallExpression *)
override;
515 : typeMap(typeMap), refMap(refMap), structure(structure) {}
516 void postorder(
const IR::P4Table *t)
override;
525 IR::IndexedVector<IR::Declaration> toInsert;
526 IR::IndexedVector<IR::StatOrDecl> statements;
528 cstring createTemporary(
const IR::Type *type);
530 const IR::Expression *expression);
534 : typeMap(typeMap), refMap(refMap) {}
535 const IR::Node *preorder(IR::Mux *expression)
override;
536 const IR::Node *postorder(IR::P4Parser *parser)
override;
537 const IR::Node *postorder(IR::Function *function)
override;
538 const IR::Node *postorder(IR::P4Control *control)
override;
539 const IR::Node *postorder(IR::P4Action *action)
override;
540 const IR::Node *postorder(IR::AssignmentStatement *statement)
override;
553 std::vector<cstring> *csum_vec;
558 std::vector<cstring> *csum_vec)
559 : typeMap(typeMap), structure(structure), csum_vec(csum_vec) {}
560 bool preorder(
const IR::Declaration_Instance *d)
override {
561 auto type = typeMap->getType(d,
true);
562 if (
auto extn = type->to<IR::Type_Extern>()) {
563 if (extn->name ==
"InternetChecksum") {
564 std::ostringstream s;
565 s <<
"state_" << index++;
566 csum_vec->push_back(s.str());
567 structure->csum_map.emplace(d, s.str());
579 std::vector<cstring> *csum_vec;
583 std::vector<cstring> *csum_vec)
584 : structure(structure), csum_vec(csum_vec) {}
586 const IR::Node *postorder(IR::P4Program *p)
override {
588 bool inserted =
false;
589 for (
auto obj : p->objects) {
590 if (obj->to<IR::Type_Header>() && !inserted) {
592 if (csum_vec->size() > 0) {
593 auto fields =
new IR::IndexedVector<IR::StructField>;
594 for (
auto fld : *csum_vec) {
596 new IR::StructField(IR::ID(fld),
new IR::Type_Bits(16,
false)));
598 new_objs->push_back(
new IR::Type_Header(IR::ID(
"cksum_state_t"), *fields));
601 new_objs->push_back(obj);
603 p->objects = *new_objs;
607 const IR::Node *postorder(IR::Type_Struct *s)
override {
608 if (s->name.name == structure->header_type) {
609 if (structure->csum_map.size() > 0)
610 s->fields.push_back(
new IR::StructField(
611 IR::ID(
"cksum_state"),
new IR::Type_Name(IR::ID(
"cksum_state_t"))));
618 std::vector<cstring> csum_vec;
634 bool preorder(
const IR::Declaration_Instance *d)
override {
635 if (
auto type = d->type->to<IR::Type_Name>()) {
636 auto externTypeName = type->path->name.name;
637 if (externTypeName ==
"DirectMeter") {
638 if (d->arguments->size() != 1) {
639 ::error(ErrorType::ERR_EXPECTED,
640 "%1%: expected type of meter as the only argument", d);
643 if (d->arguments->at(0)->expression->to<IR::Constant>()->asUnsigned() == 0)
644 warn(ErrorType::WARN_UNSUPPORTED,
645 "%1%: Packet metering is not supported."
646 " Falling back to byte metering.",
653 structure->externDecls.push_back(d);
654 }
else if (
auto type = d->type->to<IR::Type_Specialized>()) {
655 auto externTypeName = type->baseType->path->name.name;
656 if (externTypeName ==
"Meter") {
657 if (d->arguments->size() != 2) {
658 ::error(ErrorType::ERR_EXPECTED,
659 "%1%: expected number of meters and type of meter as arguments", d);
662 if (d->arguments->at(1)->expression->to<IR::Constant>()->asUnsigned() == 0)
663 warn(ErrorType::WARN_UNSUPPORTED,
664 "%1%: Packet metering is not supported."
665 " Falling back to byte metering.",
668 }
else if (externTypeName ==
"Counter") {
669 if (d->arguments->size() != 2) {
670 ::error(ErrorType::ERR_EXPECTED,
671 "%1%: expected number of counters and type of counter as arguments", d);
673 }
else if (externTypeName ==
"DirectCounter") {
674 if (d->arguments->size() != 1) {
675 ::error(ErrorType::ERR_EXPECTED,
676 "%1%: expected type of counter as the only argument", d);
678 }
else if (externTypeName ==
"Register") {
679 if (d->arguments->size() != 1 && d->arguments->size() != 2) {
680 ::error(ErrorType::ERR_EXPECTED,
681 "%1%: expected size and optionally init_val as arguments", d);
683 }
else if (externTypeName ==
"Hash") {
684 if (d->arguments->size() != 1) {
685 ::error(ErrorType::ERR_EXPECTED,
686 "%1%: expected hash algorithm as the only argument", d);
692 structure->externDecls.push_back(d);
704 const IR::Node *postorder(IR::LAnd *land) {
705 if (
auto land2 = land->left->to<IR::LAnd>()) {
706 auto sub =
new IR::LAnd(land2->right, land->right);
707 return new IR::LAnd(land2->left, sub);
708 }
else if (!land->left->is<IR::LOr>() && !land->left->is<IR::Equ>() &&
709 !land->left->is<IR::Neq>() && !land->left->is<IR::Leq>() &&
710 !land->left->is<IR::Geq>() && !land->left->is<IR::Lss>() &&
711 !land->left->is<IR::Grt>() && !land->left->is<IR::MethodCallExpression>() &&
712 !land->left->is<IR::PathExpression>() && !land->left->is<IR::Member>()) {
713 BUG(
"Logical Expression Unroll pass failed");
717 const IR::Node *postorder(IR::LOr *lor) {
718 if (
auto lor2 = lor->left->to<IR::LOr>()) {
719 auto sub =
new IR::LOr(lor2->right, lor->right);
720 return new IR::LOr(lor2->left, sub);
721 }
else if (!lor->left->is<IR::LAnd>() && !lor->left->is<IR::Equ>() &&
722 !lor->left->is<IR::Neq>() && !lor->left->is<IR::Lss>() &&
723 !lor->left->is<IR::Grt>() && !lor->left->is<IR::MethodCallExpression>() &&
724 !lor->left->is<IR::PathExpression>() && !lor->left->is<IR::Member>()) {
725 BUG(
"Logical Expression Unroll pass failed");
736 bool is_simple(
const IR::Node *n) {
737 if (n->is<IR::Equ>() || n->is<IR::Neq>() || n->is<IR::Lss>() || n->is<IR::Grt>() ||
738 n->is<IR::Geq>() || n->is<IR::Leq>() || n->is<IR::MethodCallExpression>() ||
739 n->is<IR::PathExpression>() || n->is<IR::Member>()) {
741 }
else if (!n->is<IR::LAnd>() && !n->is<IR::LOr>()) {
742 BUG(
"Logical Expression Unroll pass failed");
749 const IR::Node *postorder(IR::LAnd *land) {
750 if (!is_simple(land->left) && is_simple(land->right)) {
751 return new IR::LAnd(land->right, land->left);
752 }
else if (!is_simple(land->left)) {
753 if (
auto land2 = land->right->to<IR::LAnd>()) {
754 if (is_simple(land2->left)) {
755 auto sub =
new IR::LAnd(land->left, land2->right);
756 return new IR::LAnd(land2->left, sub);
762 const IR::Node *postorder(IR::LOr *lor) {
763 if (!is_simple(lor->left) && is_simple(lor->right)) {
764 return new IR::LOr(lor->right, lor->left);
765 }
else if (!is_simple(lor->left)) {
766 if (
auto lor2 = lor->right->to<IR::LOr>()) {
767 if (is_simple(lor2->left)) {
768 auto sub =
new IR::LOr(lor->left, lor2->right);
769 return new IR::LOr(lor2->left, sub);
800 setName(
"CollectTableInfo");
802 bool preorder(
const IR::Key *key)
override;
813 int offsetInMetadata;
819 int numExistingMetaFields;
823 std::vector<struct keyElementInfo *> elements;
827 IR::IndexedVector<IR::Declaration> decls;
833 std::set<const IR::P4Table *> *invokedInKey,
836 setName(
"CopyMatchKeysToSingleStruct");
839 const IR::Node *preorder(IR::Key *key)
override;
840 const IR::Node *postorder(IR::KeyElement *element)
override;
841 const IR::Node *doStatement(
const IR::Statement *statement,
842 const IR::Expression *expression)
override;
843 struct keyInfo *getKeyInfo(IR::Key *keys);
844 cstring getTableKeyName(
const IR::Expression *e);
845 int getFieldSizeBits(
const IR::Type *field_type);
846 bool isLearnerTable(
const IR::P4Table *t);
853 std::map<cstring, std::vector<std::tuple<cstring, IR::Constant *>>> actionCaseMap;
857 void addToSwitchMap(
cstring actionName,
cstring switchExprTmp, IR::Constant *caseLabelValue) {
858 actionCaseMap[actionName].push_back(std::make_tuple(switchExprTmp, caseLabelValue));
861 const IR::Node *setSwitchVarInAction(IR::P4Action *action) {
862 if (actionCaseMap.count(action->name.name)) {
865 auto acm = actionCaseMap[action->name.name];
866 auto body =
new IR::BlockStatement(action->body->srcInfo);
867 for (
auto pair : acm) {
868 auto assn =
new IR::AssignmentStatement(
869 new IR::PathExpression(IR::ID(get<0>(pair))), get<1>(pair));
870 body->push_back(assn);
872 for (
auto s : action->body->components) body->push_back(s);
874 actionCaseMap.erase(action->name.name);
888 enum class TableImplementation { DEFAULT, ACTION_PROFILE, ACTION_SELECTOR };
893 TableImplementation implementation;
894 std::set<cstring> match_tables;
895 std::map<cstring, cstring> group_tables;
896 std::map<cstring, cstring> member_tables;
897 std::map<cstring, cstring> member_ids;
898 std::map<cstring, cstring> group_ids;
902 : refMap(refMap), typeMap(typeMap), structure(structure), sw(sw) {
903 implementation = TableImplementation::DEFAULT;
906 const IR::Node *postorder(IR::MethodCallStatement *)
override;
907 const IR::Node *postorder(IR::IfStatement *)
override;
908 const IR::Node *postorder(IR::SwitchStatement *)
override;
909 const IR::Node *postorder(IR::P4Control *)
override;
910 std::tuple<const IR::P4Table *, cstring, cstring> create_match_table(
911 const IR::P4Table * );
913 const IR::P4Table *create_member_table(
const IR::P4Table *,
cstring,
cstring);
916 IR::Expression *initializeMemberAndGroupId(
cstring tableName,
917 IR::IndexedVector<IR::StatOrDecl> *decls);
931 implementation = TableImplementation::ACTION_SELECTOR;
933 const IR::Node *postorder(IR::P4Table *tbl)
override;
946 implementation = TableImplementation::ACTION_PROFILE;
948 const IR::Node *postorder(IR::P4Table *tbl)
override;
975 const IR::Node *postorder(IR::P4Action *action) {
return sw.setSwitchVarInAction(action); }
1010 bool methodCallFound;
1011 int getTableSize(
const IR::P4Table *tbl);
1012 bool ifMethodFound(
const IR::P4Action *a,
cstring method,
cstring instancename =
"");
1019 : refMap(refMap), typeMap(typeMap), structure(structure) {
1020 setName(
"CollectDirectCounterMeter");
1021 visitDagOnce =
false;
1025 methodCallFound =
false;
1028 bool preorder(
const IR::MethodCallStatement *mcs)
override;
1029 bool preorder(
const IR::AssignmentStatement *assn)
override;
1030 bool preorder(
const IR::P4Action *a)
override;
1031 bool preorder(
const IR::P4Table *t)
override;
1043 : refMap(refMap), typeMap(typeMap), structure(structure) {}
1045 void postorder(
const IR::AssignmentStatement *)
override;
1046 void postorder(
const IR::MethodCallStatement *)
override;
1057 : refMap(refMap), typeMap(typeMap), structure(structure) {}
1059 void postorder(
const IR::P4Table *t)
override;
1060 void postorder(
const IR::MethodCallStatement *)
override;
1071 : refMap(refMap), typeMap(typeMap), structure(structure) {}
1073 void postorder(
const IR::MethodCallStatement *)
override;
1074 cstring getDefActionName(
const IR::P4Table *t) {
1075 auto act = t->getDefaultAction();
1076 BUG_CHECK(act !=
nullptr,
"%1%: default action does not exist", t);
1077 if (
auto mc = act->to<IR::MethodCallExpression>()) {
1078 auto method = mc->method->to<IR::PathExpression>();
1079 return method->path->name;
1090 void isValidOperandSize(
const IR::Expression *e) {
1091 if (
auto t = e->type->to<IR::Type_Bits>()) {
1092 if (t->width_bits() > dpdk_max_operand_size) {
1093 ::error(ErrorType::ERR_UNSUPPORTED_ON_TARGET,
"Unsupported bitwidth %1% in %2%",
1094 t->width_bits(), e);
1100 void postorder(
const IR::Operation_Binary *binop)
override {
1101 isValidOperandSize(binop->left);
1102 isValidOperandSize(binop->right);
1106 void postorder(
const IR::Operation_Unary *unop)
override {
1107 if (unop->is<IR::Cast>())
return;
1108 isValidOperandSize(unop->expr);
1111 void postorder(
const IR::Operation_Ternary *top)
override {
1112 isValidOperandSize(top->e0);
1113 isValidOperandSize(top->e1);
1114 isValidOperandSize(top->e2);
1123 CHECK_NULL(structure);
1125 void postorder(
const IR::Type_Error *error)
override {
1127 for (
auto err : error->members) {
1128 if (structure->error_map.count(err->name.name) == 0) {
1129 structure->error_map.emplace(err->name.name,
id++);
1173 bool isHeader(
const IR::Expression *e);
1174 const IR::Node *preorder(IR::AssignmentStatement *as)
override;
1175 const IR::Node *preorder(IR::MethodCallStatement *mcs)
override;
1176 const IR::Node *postorder(IR::Member *m)
override;
1194 bool &is_all_arg_header_fields;
1198 : is_all_arg_header_fields(is_all_arg_header_fields) {}
1199 bool preorder(
const IR::AssignmentStatement *assn)
override {
1200 if (!is_all_arg_header_fields)
return false;
1201 if ((isLargeFieldOperand(assn->left) && !isLargeFieldOperand(assn->right) &&
1202 !isInsideHeader(assn->right)) ||
1203 (isLargeFieldOperand(assn->left) && assn->right->is<IR::Constant>()) ||
1204 (!isLargeFieldOperand(assn->left) && isLargeFieldOperand(assn->right) &&
1205 !isInsideHeader(assn->left))) {
1206 is_all_arg_header_fields &=
false;
1217 bool &is_all_arg_header_fields;
1221 : typeMap(typeMap), is_all_arg_header_fields(is_all_arg_header_fields) {}
1222 bool preorder(
const IR::MethodCallExpression *mce)
override {
1223 if (!is_all_arg_header_fields)
return false;
1224 if (
auto *m = mce->method->to<IR::Member>()) {
1225 if (
auto *type = typeMap->getType(m->expr)->to<IR::Type_Extern>()) {
1226 if (type->name ==
"InternetChecksum") {
1227 if (m->member ==
"add" || m->member ==
"subtract") {
1228 for (
auto arg : *mce->arguments) {
1229 if (
auto se = arg->expression->to<IR::StructExpression>()) {
1230 for (
auto c : se->components) {
1231 if (
auto m0 = c->expression->to<IR::Member>()) {
1232 if (!typeMap->getType(m0->expr,
true)
1233 ->is<IR::Type_Header>()) {
1234 is_all_arg_header_fields =
false;
1238 is_all_arg_header_fields =
false;
1242 }
else if (arg->expression->to<IR::Constant>()) {
1243 is_all_arg_header_fields =
false;
1245 }
else if (
auto m = arg->expression->to<IR::Member>()) {
1246 if (!(typeMap->getType(m->expr,
true)->is<IR::Type_Header>() ||
1247 typeMap->getType(m,
true)->is<IR::Type_Header>())) {
1248 is_all_arg_header_fields =
false;
1270 bool &is_all_args_header;
1274 static cstring pseudoHeaderInstanceName;
1275 static cstring pseudoHeaderTypeName;
1277 bool &is_all_args_header)
1278 : refMap(refMap), typeMap(typeMap), is_all_args_header(is_all_args_header) {
1279 pseudoHeaderInstanceName = refMap->
newName(
"dpdk_pseudo_header");
1280 pseudoHeaderTypeName = refMap->
newName(
"dpdk_pseudo_header_t");
1281 (void)this->typeMap;
1285 const IR::Node *preorder(IR::P4Program *program)
override;
1286 const IR::Node *preorder(IR::Type_Struct *st)
override;
1307 bool &is_all_args_header;
1311 static std::vector<std::pair<cstring, const IR::Type *>> pseudoFieldNameType;
1313 bool &is_all_args_header)
1314 : refMap(refMap), typeMap(typeMap), is_all_args_header(is_all_args_header) {}
1315 std::pair<IR::AssignmentStatement *, IR::Member *> addAssignmentStmt(
const IR::Expression *ne);
1317 const IR::Node *postorder(IR::P4Program *p)
override {
1318 if (newStructTypes.size() > 0) {
1320 allTypeDecls.append(newStructTypes);
1321 allTypeDecls.append(p->objects);
1322 p->objects = allTypeDecls;
1326 const IR::Node *postorder(IR::MethodCallStatement *statement)
override;
1327 const IR::Node *postorder(IR::AssignmentStatement *statement)
override;
1335 bool &is_all_args_header;
1339 bool &is_all_args_header)
1340 : refMap(refMap), typeMap(typeMap), is_all_args_header(is_all_args_header) {
1341 (void)this->typeMap;
1344 const IR::Node *preorder(IR::Type_Header *h)
override;
1350 bool &is_all_args_header;
1354 bool &is_all_args_header_fields)
1355 : refMap(refMap), typeMap(typeMap), is_all_args_header(is_all_args_header_fields) {
1385 passes.push_back(evaluator);
1386 passes.push_back(
new VisitFunctor([evaluator, parseDpdk]() {
1387 auto toplevel = evaluator->getToplevelBlock();
1388 auto main = toplevel->getMain();
1389 if (main ==
nullptr) {
1390 ::error(ErrorType::ERR_NOT_FOUND,
1391 "Could not locate top-level block; is there a %1% module?",
1392 IR::P4Program::main);
1395 main->apply(*parseDpdk);
1407 const IR::Node *preorder(IR::Type_Struct *s)
override;
1408 const IR::Node *postorder(IR::P4Control *c)
override;
1409 const IR::Node *postorder(IR::P4Program *p)
override;
1410 const IR::Node *postorder(IR::P4Parser *c)
override;
1420 : refMap(refMap), typeMap(typeMap) {}
1421 const IR::Node *postorder(IR::P4Parser *c)
override;
1422 const IR::Node *preorder(IR::PathExpression *path)
override;
1423 static const IR::Type_Struct *metadataStrct;
1424 static std::map<cstring, const IR::Type *> fieldNameType;
1449 bool &is_ipsec_used;
1458 : is_ipsec_used(is_ipsec_used),
1459 sa_id_width(sa_id_width),
1462 structure(structure) {}
1463 bool preorder(
const IR::MethodCallStatement *mcs)
override {
1466 if (a->originalExternType->getName().name ==
"ipsec_accelerator") {
1467 if (structure->
isPSA()) {
1468 ::error(ErrorType::ERR_MODEL,
"%1% is not available for PSA programs",
1469 a->originalExternType->getName().name);
1472 if (a->method->getName().name ==
"enable") {
1473 is_ipsec_used =
true;
1474 }
else if (a->method->getName().name ==
"set_sa_index") {
1475 auto typeArgs = a->expr->typeArguments;
1476 if (typeArgs->size() != 1) {
1477 ::error(ErrorType::ERR_MODEL,
"Unexpected number of type arguments for %1%",
1481 auto width = typeArgs->at(0);
1482 if (!width->is<IR::Type_Bits>()) {
1483 ::error(ErrorType::ERR_MODEL,
"Unexpected width type %1% for sa_index",
1487 sa_id_width = width->to<IR::Type_Bits>()->width_bits();
1503 bool &is_ipsec_used;
1505 cstring newHeaderName =
"platform_hdr_t";
1506 IR::Type_Header *ipsecHeader =
nullptr;
1507 std::vector<cstring> registerInstanceNames = {
1508 "ipsec_port_out_inbound",
"ipsec_port_out_outbound",
"ipsec_port_in_inbound",
1509 "ipsec_port_in_outbound"};
1513 bool &is_ipsec_used,
int &sa_id_width)
1515 structure(structure),
1516 is_ipsec_used(is_ipsec_used),
1517 sa_id_width(sa_id_width) {
1518 setName(
"InsertReqDeclForIPSec");
1521 const IR::Node *preorder(IR::P4Program *program)
override;
1522 const IR::Node *preorder(IR::Type_Struct *s)
override;
1523 const IR::Node *preorder(IR::P4Control *c)
override;
1524 IR::IndexedVector<IR::StatOrDecl> *addRegDeclInstance(std::vector<cstring> portRegs);
1531 bool is_ipsec_used =
false;
1532 int sa_id_width = 32;
1536 : refMap(refMap), typeMap(typeMap), structure(structure) {
1538 new CollectIPSecInfo(is_ipsec_used, sa_id_width, refMap, typeMap, structure));
Definition dpdkArch.h:702
Definition dpdkArch.h:1049
Definition dpdkArch.h:1000
Definition dpdkArch.h:1118
Definition dpdkArch.h:629
Definition dpdkArch.h:1448
Definition dpdkArch.h:550
Definition dpdkArch.h:1430
Definition dpdkArch.h:449
Definition dpdkArch.h:1379
Definition dpdkArch.h:1414
Definition dpdkArch.h:795
Definition dpdkArch.h:979
Definition dpdkArch.h:433
Definition dpdkArch.h:617
Definition dpdkArch.h:782
Definition dpdkArch.h:165
void postorder(const IR::AssignmentStatement *statement) override
Definition dpdkArch.cpp:216
Definition dpdkArch.h:176
Definition dpdkArch.h:107
Definition dpdkArch.h:826
Definition dpdkArch.h:286
Definition dpdkArch.h:508
Definition dpdkArch.h:522
Definition dpdkArch.h:1369
Definition dpdkArch.h:1374
Definition dpdkArch.h:361
This pass checks whether an assignment statement has large operands (>64-bit).
Definition dpdkArch.h:1193
Definition dpdkArch.h:383
Definition dpdkArch.h:215
Definition dpdkArch.h:1500
Definition dpdkArch.h:402
Definition dpdkArch.h:487
Definition dpdkArch.h:941
Definition dpdkArch.h:926
Definition dpdkArch.h:883
Definition dpdkArch.h:338
Definition dpdkArch.h:735
Definition dpdkArch.h:849
Definition dpdkArch.h:970
Definition dpdkArch.h:1063
Definition dpdkArch.h:1034
Definition dpdkArch.h:1087
Definition externInstance.h:33
Definition typeChecker.h:37
Definition removeLeftSlices.h:35
Definition evaluator.h:114
Definition methodInstance.h:144
Definition flattenInterfaceStructs.h:252
Definition sideEffects.h:294
static MethodInstance * resolve(const IR::MethodCallExpression *mce, DeclarationLookup *refMap, TypeMap *typeMap, bool useExpressionType=false, const Visitor::Context *ctxt=nullptr, bool incomplete=false)
Definition methodInstance.cpp:26
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
cstring newName(cstring base) override
Generate a name from base that fresh for the program.
Definition referenceMap.cpp:96
Definition resolveReferences.h:119
Definition typeChecker.h:60
Definition typeChecker.h:83
Definition dpdkProgramStructure.h:121
Definition source_file.h:126
Definition ordered_map.h:30
Definition backend.cpp:35
Definition dpdkArch.h:812
Definition dpdkArch.h:817
Definition dpdkArch.h:251
Definition dpdkArch.h:106
Definition dpdkArch.h:1527
Definition dpdkArch.h:276
Definition dpdkProgramStructure.h:14
bool isPSA(void)
Predicate that states whether architecture is PSA or not.
Definition dpdkProgramStructure.h:89