P4C
The P4 Compiler
Loading...
Searching...
No Matches
dpdkHelpers.h
1/*
2Copyright 2020 Intel Corp.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef BACKENDS_DPDK_DPDKHELPERS_H_
18#define BACKENDS_DPDK_DPDKHELPERS_H_
19
20#include "constants.h"
21#include "dpdkProgramStructure.h"
22#include "frontends/common/constantFolding.h"
23#include "frontends/common/resolveReferences/referenceMap.h"
24#include "frontends/p4/coreLibrary.h"
25#include "frontends/p4/enumInstance.h"
26#include "frontends/p4/evaluator/evaluator.h"
27#include "frontends/p4/methodInstance.h"
28#include "frontends/p4/simplify.h"
29#include "frontends/p4/typeMap.h"
30#include "frontends/p4/unusedDeclarations.h"
31#include "ir/ir.h"
32#include "lib/big_int_util.h"
33#include "lib/json.h"
34#include "midend/removeComplexExpressions.h"
35
36#define TOSTR_DECLA(NAME) std::ostream &toStr(std::ostream &, IR::NAME *)
37
38namespace P4::DPDK {
39
40static const int SupportedBitWidth = 128;
41
43
52const char PnaMainOutputMetadataOutputPortName[] = "pna_main_output_metadata_output_port";
53const char DirectResourceTableEntryIndex[] = "table_entry_index";
54
55/* This class will generate a optimized jmp and label control flow.
56 * Couple of examples here
57 *
58 * Example 1:
59 * If(a && b){
60 *
61 * }
62 * Else{
63 *
64 * }
65 *
66 * Will be translated to(in an optimal form):
67 * cmp a 1
68 * jneq false
69 * cmp b 1
70 * jneq false
71 * true:
72 * // if true statements go here
73 * jmp end
74 * false:
75 * // if false statements go here
76 * end:
77 *
78 * In this case, in order to use fewer jmp, I use jneq instead of jeq to let the
79 * true condition fall through the jmp statement and short-circuit the false
80 * condition.
81 *
82 * Example 2:
83 * (a && b) || c
84 * cmp a 1
85 * jneq half_false
86 * cmp b 1
87 * jneq half_false
88 * jmp true
89 * half_false:
90 * cmp c 1
91 * jeq true
92 * false:
93 *
94 * jmp end
95 * true:
96 *
97 * end:
98 *
99 * In this case, it is not in an optimal form. To make it optimal, I need to
100 * change (a && b) || c to c ||(a && b) and assembly code looks like this:
101 * cmp c 1
102 * jeq true
103 * cmp a 1
104 * jneq false
105 * cmp b 1
106 * jneq false
107 * false:
108 *
109 * jmp end
110 * true:
111 *
112 * end:
113 *
114 * It is very important to generate as fewer jmp and label instructions as
115 * possible, because the performance of DPDK is directly related to the number
116 * of instructions.
117 *
118 * This class uses a recursive function to generate the control flow and is
119 * optmized.
120 */
121class BranchingInstructionGeneration {
122 ConvertStatementToDpdk *convert;
123 P4::ReferenceMap *refMap;
124 P4::TypeMap *typeMap;
125 bool nested(const IR::Node *n) {
126 if (n->is<IR::LAnd>() || n->is<IR::LOr>()) {
127 return true;
128 } else {
129 return false;
130 }
131 }
132
133 public:
134 BranchingInstructionGeneration(ConvertStatementToDpdk *convert, P4::ReferenceMap *refMap,
135 P4::TypeMap *typeMap)
136 : convert(convert), refMap(refMap), typeMap(typeMap) {}
137 bool generate(const IR::Expression *, cstring, cstring, bool);
138};
139
140class TypeWidthValidator : public Inspector {
141 void postorder(const IR::Type_Varbits *type) override {
142 LOG3("Validating Type_Varbits: " << type);
143 if (type->size % 8 != 0) {
144 ::P4::error(ErrorType::ERR_UNSUPPORTED, "%1% varbit width (%2%) not aligned to 8 bits",
145 type->srcInfo, type->size);
146 }
147 }
148};
149
150class ConvertStatementToDpdk : public Inspector {
152 P4::TypeMap *typemap;
153 P4::ReferenceMap *refmap;
154 DpdkProgramStructure *structure;
155 const IR::P4Parser *parser = nullptr;
156 const IR::Node *parent = nullptr;
157 IR::Type_Struct *metadataStruct = nullptr;
158 bool createSandboxHeaderType = false;
159 bool createTmpVar = false;
160
161 private:
162 void processHashParams(const IR::Argument *field, IR::Vector<IR::Expression> &components);
163 bool checkIfBelongToSameHdrMdStructure(const IR::Argument *field);
164 void updateMdStrAndGenInstr(const IR::Argument *field, IR::Vector<IR::Expression> &components);
165 cstring getHdrMdStrName(const IR::Member *mem);
166 bool checkIfConsecutiveHdrMdfields(const IR::Argument *field);
167 void createSandboxHeader();
168 void createTmpVarForSandbox();
169 friend class BranchingInstructionGeneration;
170
171 public:
172 ConvertStatementToDpdk(P4::ReferenceMap *refmap, P4::TypeMap *typemap,
173 DpdkProgramStructure *structure)
174 : typemap(typemap), refmap(refmap), structure(structure) {
175 visitDagOnce = false;
176 }
177 ConvertStatementToDpdk(P4::ReferenceMap *refmap, P4::TypeMap *typemap,
178 DpdkProgramStructure *structure, IR::Type_Struct *metadataStruct)
179 : typemap(typemap), refmap(refmap), structure(structure), metadataStruct(metadataStruct) {
180 visitDagOnce = false;
181 }
182 IR::IndexedVector<IR::DpdkAsmStatement> getInstructions() { return instructions; }
183 void branchingInstructionGeneration(cstring true_label, cstring false_label,
184 const IR::Expression *expr);
185 bool preorder(const IR::AssignmentStatement *a) override;
186 bool preorder(const IR::IfStatement *a) override;
187 bool preorder(const IR::MethodCallStatement *a) override;
188 bool preorder(const IR::SwitchStatement *a) override;
189
190 void add_instr(const IR::DpdkAsmStatement *s) { instructions.push_back(s); }
191 IR::IndexedVector<IR::DpdkAsmStatement> &get_instr() { return instructions; }
192 void process_logical_operation(const IR::Expression *, const IR::Operation_Binary *);
193 void process_relation_operation(const IR::Expression *, const IR::Operation_Relation *);
194 cstring append_parser_name(const IR::P4Parser *p, cstring);
195 void set_parser(const IR::P4Parser *p) { parser = p; }
196 void set_parent(const IR::Node *p) { parent = p; }
197 bool handleConstSwitch(const IR::SwitchStatement *a);
198 bool checkIf128bitOp(const IR::Expression *, const IR::Expression *);
199 void add128bitwiseInstr(const IR::Expression *src1Op, const IR::Expression *src2Op,
200 const char *op);
201 void add128ComparisonInstr(cstring true_label, const IR::Expression *src1Op,
202 const IR::Expression *src2Op, const char *op);
203 void add128bitComplInstr(const IR::Expression *, const IR::Expression *);
204 void add128bitMovInstr(const IR::Expression *left, const IR::Expression *right);
205};
206
207class ProcessControls : public P4::RemoveComplexExpressionsPolicy {
208 const std::set<cstring> *process;
209
210 public:
211 explicit ProcessControls(const std::set<cstring> *process) : process(process) {
212 CHECK_NULL(process);
213 }
214 bool convert(const IR::P4Control *control) const {
215 if (process->find(control->name) != process->end()) return true;
216 return false;
217 }
218};
219
220} // namespace P4::DPDK
221#endif /* BACKENDS_DPDK_DPDKHELPERS_H_ */
bool generate(const IR::Expression *, cstring, cstring, bool)
Definition dpdkHelpers.cpp:820
Definition dpdkHelpers.h:150
void process_relation_operation(const IR::Expression *, const IR::Operation_Relation *)
Definition dpdkHelpers.cpp:31
bool preorder(const IR::AssignmentStatement *a) override
Definition dpdkHelpers.cpp:124
bool convert(const IR::P4Control *control) const
Definition dpdkHelpers.h:214
Definition dpdkHelpers.h:140
Definition indexed_vector.h:40
Definition node.h:94
Definition vector.h:59
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Definition removeComplexExpressions.h:30
Definition typeMap.h:41
Definition cstring.h:85
Definition dpdk/backend.cpp:37
const char PnaMainOutputMetadataOutputPortName[]
Name of the metadata used as output port.
Definition dpdkHelpers.h:52
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58
Collect information related to P4 programs targeting dpdk.
Definition dpdkProgramStructure.h:16
bool is() const noexcept
Definition rtti.h:216