P4C
The P4 Compiler
Loading...
Searching...
No Matches
dpdkCheckExternInvocation.h
1/*
2 * Copyright 2021 Intel Corp.
3 * SPDX-FileCopyrightText: 2021 Intel Corp.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef BACKENDS_DPDK_DPDKCHECKEXTERNINVOCATION_H_
9#define BACKENDS_DPDK_DPDKCHECKEXTERNINVOCATION_H_
10
11#include <array>
12
13#include "dpdkProgramStructure.h"
14#include "frontends/p4/methodInstance.h"
15#include "ir/ir.h"
16#include "ir/visitor.h"
17#include "lib/cstring.h"
18#include "midend/checkExternInvocationCommon.h"
19
20namespace P4 {
21class TypeMap;
22} // namespace P4
23
24namespace P4::DPDK {
25
26using namespace P4::literals;
27
30
31class CheckPNAExternInvocation : public P4::CheckExternInvocationCommon {
32 DpdkProgramStructure *structure;
33
34 enum block_t {
35 MAIN_PARSER = 0,
36 PRE_CONTROL,
37 MAIN_CONTROL,
38 MAIN_DEPARSER,
39 BLOCK_COUNT,
40 };
41
42 void initPipeConstraints() override {
43 bitvec validInMainControl;
44 validInMainControl.setbit(MAIN_CONTROL);
45 setPipeConstraints("send_to_port"_cs, validInMainControl);
46 setPipeConstraints("mirror_packet"_cs, validInMainControl);
47 // Add new constraints here
48 }
49
50 cstring getBlockName(int bit) override {
51 static const std::array<cstring, BLOCK_COUNT> lookup = {
52 "main parser"_cs, "pre control"_cs, "main control"_cs, "main deparser"_cs};
53 return lookup[bit % BLOCK_COUNT];
54 }
55
56 const IR::P4Parser *getParser(const cstring parserName) {
57 if (auto p = findContext<IR::P4Parser>()) {
58 if (structure->parsers.count(parserName) != 0 &&
59 structure->parsers.at(parserName)->name == p->name) {
60 return p;
61 }
62 }
63 return nullptr;
64 }
65
66 const IR::P4Control *getControl(const cstring controlName) {
67 if (auto c = findContext<IR::P4Control>()) {
68 if (structure->pipelines.count(controlName) != 0 &&
69 structure->pipelines.at(controlName)->name == c->name) {
70 return c;
71 }
72 }
73 return nullptr;
74 }
75
76 const IR::P4Control *getDeparser(const cstring deparserName) {
77 if (auto d = findContext<IR::P4Control>()) {
78 if (structure->deparsers.count(deparserName) != 0 &&
79 structure->deparsers.at(deparserName)->name == d->name) {
80 return d;
81 }
82 }
83 return nullptr;
84 }
85
86 void checkBlock(const IR::MethodCallExpression *expr, const cstring externType,
87 const cstring externName) {
88 bitvec pos;
89
90 LOG4("externType: " << externType << ", externName: " << externName);
91
92 if (pipeConstraints.count(externType)) {
93 if (auto block = getParser("MainParserT"_cs)) {
94 LOG4("MainParser: " << (void *)block << " " << dbp(block));
95 pos.setbit(MAIN_PARSER);
96 checkPipeConstraints(externType, pos, expr, externName, block->name);
97 } else if (auto block = getControl("PreControlT"_cs)) {
98 LOG4("PreControl: " << (void *)block << " " << dbp(block));
99 pos.setbit(PRE_CONTROL);
100 checkPipeConstraints(externType, pos, expr, externName, block->name);
101 } else if (auto block = getControl("MainControlT"_cs)) {
102 LOG4("MainControl: " << (void *)block << " " << dbp(block));
103 pos.setbit(MAIN_CONTROL);
104 checkPipeConstraints(externType, pos, expr, externName, block->name);
105 } else if (auto block = getDeparser("MainDeparserT"_cs)) {
106 LOG4("MainDeparser: " << (void *)block << " " << dbp(block));
107 pos.setbit(MAIN_DEPARSER);
108 checkPipeConstraints(externType, pos, expr, externName, block->name);
109 } else {
110 LOG4("Other");
111 }
112 } else {
113 LOG1("Pipe constraints not defined for: " << externType);
114 }
115 }
116
117 void checkExtern(const P4::ExternMethod *extMethod,
118 const IR::MethodCallExpression *expr) override {
119 LOG3("ExternMethod: " << extMethod << ", MethodCallExpression: " << expr);
120 checkBlock(expr, extMethod->originalExternType->name, extMethod->object->getName().name);
121 }
122
123 void checkExtern(const P4::ExternFunction *extFunction,
124 const IR::MethodCallExpression *expr) override {
125 LOG3("ExternFunction: " << extFunction << ", MethodCallExpression: " << expr);
126 checkBlock(expr, expr->method->toString(), cstring::empty);
127 }
128
129 public:
130 CheckPNAExternInvocation(P4::TypeMap *typeMap, DpdkProgramStructure *structure)
131 : P4::CheckExternInvocationCommon(typeMap), structure(structure) {
132 initPipeConstraints();
133 }
134};
135
138class CheckExternInvocation : public Inspector {
139 P4::TypeMap *typeMap;
140 DpdkProgramStructure *structure;
141
142 public:
143 CheckExternInvocation(P4::TypeMap *typeMap, DpdkProgramStructure *structure)
144 : typeMap(typeMap), structure(structure) {}
145
146 bool preorder(const IR::P4Program *program) {
147 if (structure->isPNA()) {
148 LOG1("Checking extern invocations for PNA architecture.");
149 CheckPNAExternInvocation checker(typeMap, structure);
150 program->apply(checker, getChildContext());
151 } else if (structure->isPSA()) {
152 LOG1("Checking extern invocations for PSA architecture.");
153 // Add class checking PSA constraints here.
154 } else {
155 LOG1("Unknown architecture: " << structure->p4arch << ", not checking constraints.");
156 }
157 return false;
158 }
159};
160
161} // namespace P4::DPDK
162
163#endif /* BACKENDS_DPDK_DPDKCHECKEXTERNINVOCATION_H_ */
Base class which can be used to prepare classes for checking constraints for invocations of externs (...
Definition checkExternInvocationCommon.h:32
void setPipeConstraints(cstring extType, bitvec vec)
Set the pipe (parser/control block) constraints.
Definition checkExternInvocationCommon.h:106
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:128
Class for checking constraints for invocations of PNA architecture extern methods and functions.
Definition dpdkCheckExternInvocation.h:31
Definition methodInstance.h:194
Definition methodInstance.h:168
virtual ID getName() const =0
const IR::IDeclaration * object
Definition methodInstance.h:79
Definition typeMap.h:32
Definition bitvec.h:120
Definition cstring.h:85
Definition dpdk/backend.cpp:26
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
Collect information related to P4 programs targeting dpdk.
Definition dpdkProgramStructure.h:22