P4C
The P4 Compiler
dpdkCheckExternInvocation.h
1 /*
2 Copyright 2021 Intel Corp.
3 
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16 
17 #ifndef BACKENDS_DPDK_DPDKCHECKEXTERNINVOCATION_H_
18 #define BACKENDS_DPDK_DPDKCHECKEXTERNINVOCATION_H_
19 
20 #include "frontends/p4/methodInstance.h"
21 #include "ir/ir.h"
22 #include "ir/visitor.h"
23 #include "midend/checkExternInvocationCommon.h"
24 
25 namespace P4 {
26 class ReferenceMap;
27 class TypeMap;
28 } // namespace P4
29 
30 namespace DPDK {
31 
37  DpdkProgramStructure *structure;
38 
39  enum block_t {
40  MAIN_PARSER = 0,
41  PRE_CONTROL,
42  MAIN_CONTROL,
43  MAIN_DEPARSER,
44  BLOCK_COUNT,
45  };
46 
47  void initPipeConstraints() override {
48  bitvec validInMainControl;
49  validInMainControl.setbit(MAIN_CONTROL);
50  setPipeConstraints("send_to_port", validInMainControl);
51  setPipeConstraints("mirror_packet", validInMainControl);
52  // Add new constraints here
53  }
54 
55  cstring getBlockName(int bit) override {
56  static const char *lookup[] = {"main parser", "pre control", "main control",
57  "main deparser"};
58  BUG_CHECK(sizeof(lookup) / sizeof(lookup[0]) == BLOCK_COUNT, "Bad lookup table");
59  return lookup[bit % BLOCK_COUNT];
60  }
61 
62  const IR::P4Parser *getParser(const cstring parserName) {
63  if (auto p = findContext<IR::P4Parser>()) {
64  if (structure->parsers.count(parserName) != 0 &&
65  structure->parsers.at(parserName)->name == p->name) {
66  return p;
67  }
68  }
69  return nullptr;
70  }
71 
72  const IR::P4Control *getControl(const cstring controlName) {
73  if (auto c = findContext<IR::P4Control>()) {
74  if (structure->pipelines.count(controlName) != 0 &&
75  structure->pipelines.at(controlName)->name == c->name) {
76  return c;
77  }
78  }
79  return nullptr;
80  }
81 
82  const IR::P4Control *getDeparser(const cstring deparserName) {
83  if (auto d = findContext<IR::P4Control>()) {
84  if (structure->deparsers.count(deparserName) != 0 &&
85  structure->deparsers.at(deparserName)->name == d->name) {
86  return d;
87  }
88  }
89  return nullptr;
90  }
91 
92  void checkBlock(const IR::MethodCallExpression *expr, const cstring externType,
93  const cstring externName) {
94  bitvec pos;
95 
96  LOG4("externType: " << externType << ", externName: " << externName);
97 
98  if (pipeConstraints.count(externType)) {
99  if (auto block = getParser("MainParserT")) {
100  LOG4("MainParser: " << (void *)block << " " << dbp(block));
101  pos.setbit(MAIN_PARSER);
102  checkPipeConstraints(externType, pos, expr, externName, block->name);
103  } else if (auto block = getControl("PreControlT")) {
104  LOG4("PreControl: " << (void *)block << " " << dbp(block));
105  pos.setbit(PRE_CONTROL);
106  checkPipeConstraints(externType, pos, expr, externName, block->name);
107  } else if (auto block = getControl("MainControlT")) {
108  LOG4("MainControl: " << (void *)block << " " << dbp(block));
109  pos.setbit(MAIN_CONTROL);
110  checkPipeConstraints(externType, pos, expr, externName, block->name);
111  } else if (auto block = getDeparser("MainDeparserT")) {
112  LOG4("MainDeparser: " << (void *)block << " " << dbp(block));
113  pos.setbit(MAIN_DEPARSER);
114  checkPipeConstraints(externType, pos, expr, externName, block->name);
115  } else {
116  LOG4("Other");
117  }
118  } else {
119  LOG1("Pipe constraints not defined for: " << externType);
120  }
121  }
122 
123  void checkExtern(const P4::ExternMethod *extMethod,
124  const IR::MethodCallExpression *expr) override {
125  LOG3("ExternMethod: " << extMethod << ", MethodCallExpression: " << expr);
126  checkBlock(expr, extMethod->originalExternType->name, extMethod->object->getName().name);
127  }
128 
129  void checkExtern(const P4::ExternFunction *extFunction,
130  const IR::MethodCallExpression *expr) override {
131  LOG3("ExternFunction: " << extFunction << ", MethodCallExpression: " << expr);
132  checkBlock(expr, expr->method->toString(), "");
133  }
134 
135  public:
137  DpdkProgramStructure *structure)
138  : P4::CheckExternInvocationCommon(refMap, typeMap), structure(structure) {
139  initPipeConstraints();
140  }
141 };
142 
148  P4::ReferenceMap *refMap;
149  P4::TypeMap *typeMap;
150  DpdkProgramStructure *structure;
151 
152  public:
154  DpdkProgramStructure *structure)
155  : refMap(refMap), typeMap(typeMap), structure(structure) {}
156 
157  bool preorder(const IR::P4Program *program) {
158  if (structure->isPNA()) {
159  LOG1("Checking extern invocations for PNA architecture.");
160  auto checker = new CheckPNAExternInvocation(refMap, typeMap, structure);
161  program->apply(*checker);
162  } else if (structure->isPSA()) {
163  LOG1("Checking extern invocations for PSA architecture.");
164  // Add class checking PSA constraints here.
165  } else {
166  LOG1("Unknown architecture: " << structure->p4arch << ", not checking constraints.");
167  }
168  return false;
169  }
170 };
171 
172 } // namespace DPDK
173 
174 #endif /* BACKENDS_DPDK_DPDKCHECKEXTERNINVOCATION_H_ */
Class which chooses the correct class for checking the constraints for invocations of extern methods ...
Definition: dpdkCheckExternInvocation.h:147
Class for checking constraints for invocations of PNA architecture extern methods and functions.
Definition: dpdkCheckExternInvocation.h:36
virtual ID getName() const =0
Definition: visitor.h:396
Base class which can be used to prepare classes for checking constraints for invocations of externs (...
Definition: checkExternInvocationCommon.h:41
void setPipeConstraints(cstring extType, bitvec vec)
Set the pipe (parser/control block) constraints.
Definition: checkExternInvocationCommon.h:116
void checkPipeConstraints(cstring extType, bitvec bv, const IR::MethodCallExpression *expr, cstring extName, cstring pipe)
Check if the invocation of extern object method or extern function is valid in the block where it is ...
Definition: checkExternInvocationCommon.h:138
Definition: methodInstance.h:176
Definition: methodInstance.h:144
const IR::IDeclaration * object
Definition: methodInstance.h:79
Class used to encode maps from paths to declarations.
Definition: referenceMap.h:66
Definition: typeMap.h:42
Definition: bitvec.h:119
Definition: cstring.h:72
Definition: backend.cpp:35
Definition: applyOptionsPragmas.cpp:24
Definition: dpdkProgramStructure.h:14
bool isPSA(void)
Predicate that states whether architecture is PSA or not.
Definition: dpdkProgramStructure.h:89
bool isPNA(void)
Predicate that states whether architecture is PNA or not.
Definition: dpdkProgramStructure.h:99