46 static bool checkSameKeyExpr(
const IR::Expression *expr0,
const IR::Expression *expr1) {
47 if (expr0->node_type_name() != expr1->node_type_name())
return false;
48 if (
auto pe0 = expr0->to<IR::PathExpression>()) {
49 auto pe1 = expr1->to<IR::PathExpression>();
50 return pe0->path->name == pe1->path->name && pe0->path->absolute == pe1->path->absolute;
51 }
else if (
auto mem0 = expr0->to<IR::Member>()) {
52 auto mem1 = expr1->to<IR::Member>();
53 return checkSameKeyExpr(mem0->expr, mem1->expr) && mem0->member == mem1->member;
54 }
else if (
auto l0 = expr0->to<IR::Literal>()) {
55 auto l1 = expr1->to<IR::Literal>();
57 }
else if (
auto ai0 = expr0->to<IR::ArrayIndex>()) {
58 auto ai1 = expr1->to<IR::ArrayIndex>();
59 return checkSameKeyExpr(ai0->left, ai1->left) &&
60 checkSameKeyExpr(ai0->right, ai1->right);
68 typeMap = ctxt->typeMap;
71 bool preorder(
const IR::P4Table *table)
override {
72 auto implementation = table->properties->getProperty(
"implementation");
73 if (implementation ==
nullptr)
return false;
74 if (!implementation->value->is<IR::ExpressionValue>()) {
75 ::P4::error(ErrorType::ERR_EXPECTED,
"%1%: expected expression for property",
79 auto propv = implementation->value->to<IR::ExpressionValue>();
80 if (!propv->expression->is<IR::PathExpression>())
return false;
81 auto pathe = propv->expression->to<IR::PathExpression>();
83 if (!decl->is<IR::Declaration_Instance>()) {
84 ::P4::error(ErrorType::ERR_EXPECTED,
"%1%: expected a reference to an instance", pathe);
87 auto dcltype = typeMap->getType(pathe,
true);
88 if (!dcltype->is<IR::Type_Extern>()) {
89 ::P4::error(ErrorType::ERR_UNEXPECTED,
"%1%: unexpected type for implementation",
93 auto type_extern_name = dcltype->to<IR::Type_Extern>()->name;
95 if (type_extern_name != actionSelectorName)
return false;
97 auto key = table->getKey();
99 for (
auto ke : key->keyElements) {
100 auto mt = refMap->
getDeclaration(ke->matchType->path,
true)->
to<IR::Declaration_ID>();
101 BUG_CHECK(mt !=
nullptr,
"%1%: could not find declaration", ke->matchType);
103 input.push_back(ke->expression);
105 auto decl_instance = decl->to<IR::Declaration_Instance>();
106 auto it = ctxt->selector_input_map.find(decl_instance);
107 if (it == ctxt->selector_input_map.end()) {
108 ctxt->selector_input_map[decl_instance] = input;
113 if (i1.size() != i2.size())
return false;
114 return std::equal(i1.begin(), i1.end(), i2.begin(), checkSameKeyExpr);
117 if (!cmp_inputs(it->second, input)) {
119 ErrorType::ERR_INVALID,
120 "Action selector %1% is used by multiple tables with different selector inputs",
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:51
Definition bmv2/common/helpers.h:297
P4::ReferenceMap * refMap
context
Definition bmv2/common/helpers.h:299