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
40class ConvertStatementToDpdk;
41
50const char PnaMainOutputMetadataOutputPortName[] = "pna_main_output_metadata_output_port";
51const char DirectResourceTableEntryIndex[] = "table_entry_index";
52
53/* This class will generate a optimized jmp and label control flow.
54 * Couple of examples here
55 *
56 * Example 1:
57 * If(a && b){
58 *
59 * }
60 * Else{
61 *
62 * }
63 *
64 * Will be translated to(in an optimal form):
65 * cmp a 1
66 * jneq false
67 * cmp b 1
68 * jneq false
69 * true:
70 * // if true statements go here
71 * jmp end
72 * false:
73 * // if false statements go here
74 * end:
75 *
76 * In this case, in order to use fewer jmp, I use jneq instead of jeq to let the
77 * true condition fall through the jmp statement and short-circuit the false
78 * condition.
79 *
80 * Example 2:
81 * (a && b) || c
82 * cmp a 1
83 * jneq half_false
84 * cmp b 1
85 * jneq half_false
86 * jmp true
87 * half_false:
88 * cmp c 1
89 * jeq true
90 * false:
91 *
92 * jmp end
93 * true:
94 *
95 * end:
96 *
97 * In this case, it is not in an optimal form. To make it optimal, I need to
98 * change (a && b) || c to c ||(a && b) and assembly code looks like this:
99 * cmp c 1
100 * jeq true
101 * cmp a 1
102 * jneq false
103 * cmp b 1
104 * jneq false
105 * false:
106 *
107 * jmp end
108 * true:
109 *
110 * end:
111 *
112 * It is very important to generate as fewer jmp and label instructions as
113 * possible, because the performance of DPDK is directly related to the number
114 * of instructions.
115 *
116 * This class uses a recursive function to generate the control flow and is
117 * optmized.
118 */
120 ConvertStatementToDpdk *convert;
121 P4::ReferenceMap *refMap;
122 P4::TypeMap *typeMap;
123 bool nested(const IR::Node *n) {
124 if (n->is<IR::LAnd>() || n->is<IR::LOr>()) {
125 return true;
126 } else {
127 return false;
128 }
129 }
130
131 public:
133 P4::TypeMap *typeMap)
134 : convert(convert), refMap(refMap), typeMap(typeMap) {}
135 bool generate(const IR::Expression *, cstring, cstring, bool);
136};
137
139 void postorder(const IR::Type_Varbits *type) override {
140 LOG3("Validating Type_Varbits: " << type);
141 if (type->size % 8 != 0) {
142 ::P4::error(ErrorType::ERR_UNSUPPORTED, "%1% varbit width (%2%) not aligned to 8 bits",
143 type->srcInfo, type->size);
144 }
145 }
146};
147
150 P4::TypeMap *typemap;
151 P4::ReferenceMap *refmap;
152 DpdkProgramStructure *structure;
153 const IR::P4Parser *parser = nullptr;
154 const IR::Node *parent = nullptr;
155 IR::Type_Struct *metadataStruct = nullptr;
156 bool createSandboxHeaderType = false;
157 bool createTmpVar = false;
158
159 private:
160 void processHashParams(const IR::Argument *field, IR::Vector<IR::Expression> &components);
161 bool checkIfBelongToSameHdrMdStructure(const IR::Argument *field);
162 void updateMdStrAndGenInstr(const IR::Argument *field, IR::Vector<IR::Expression> &components);
163 cstring getHdrMdStrName(const IR::Member *mem);
164 bool checkIfConsecutiveHdrMdfields(const IR::Argument *field);
165 void createSandboxHeader();
166 void createTmpVarForSandbox();
168
169 public:
171 DpdkProgramStructure *structure)
172 : typemap(typemap), refmap(refmap), structure(structure) {
173 visitDagOnce = false;
174 }
176 DpdkProgramStructure *structure, IR::Type_Struct *metadataStruct)
177 : typemap(typemap), refmap(refmap), structure(structure), metadataStruct(metadataStruct) {
178 visitDagOnce = false;
179 }
180 IR::IndexedVector<IR::DpdkAsmStatement> getInstructions() { return instructions; }
181 void branchingInstructionGeneration(cstring true_label, cstring false_label,
182 const IR::Expression *expr);
183 bool preorder(const IR::AssignmentStatement *a) override;
184 bool preorder(const IR::IfStatement *a) override;
185 bool preorder(const IR::MethodCallStatement *a) override;
186 bool preorder(const IR::SwitchStatement *a) override;
187
188 void add_instr(const IR::DpdkAsmStatement *s) { instructions.push_back(s); }
189 IR::IndexedVector<IR::DpdkAsmStatement> &get_instr() { return instructions; }
190 void process_logical_operation(const IR::Expression *, const IR::Operation_Binary *);
191 void process_relation_operation(const IR::Expression *, const IR::Operation_Relation *);
192 cstring append_parser_name(const IR::P4Parser *p, cstring);
193 void set_parser(const IR::P4Parser *p) { parser = p; }
194 void set_parent(const IR::Node *p) { parent = p; }
195 bool handleConstSwitch(const IR::SwitchStatement *a);
196 bool checkIf128bitOp(const IR::Expression *, const IR::Expression *);
197 void add128bitwiseInstr(const IR::Expression *src1Op, const IR::Expression *src2Op,
198 const char *op);
199 void add128ComparisonInstr(cstring true_label, const IR::Expression *src1Op,
200 const IR::Expression *src2Op, const char *op);
201 void add128bitComplInstr(const IR::Expression *, const IR::Expression *);
202};
205 const std::set<cstring> *process;
206
207 public:
208 explicit ProcessControls(const std::set<cstring> *process) : process(process) {
209 CHECK_NULL(process);
210 }
211 bool convert(const IR::P4Control *control) const {
212 if (process->find(control->name) != process->end()) return true;
213 return false;
214 }
215};
216
217} // namespace P4::DPDK
218#endif /* BACKENDS_DPDK_DPDKHELPERS_H_ */
Definition dpdkHelpers.h:119
bool generate(const IR::Expression *, cstring, cstring, bool)
Definition dpdkHelpers.cpp:815
Definition dpdkHelpers.h:148
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
Only simplify complex expression in ingress/egress.
Definition dpdkHelpers.h:204
bool convert(const IR::P4Control *control) const
Definition dpdkHelpers.h:211
Definition dpdkHelpers.h:138
Definition node.h:52
Definition node.h:95
Definition vector.h:59
Definition visitor.h:400
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:50
const IR::Expression * convert(const IR::Expression *expression, const IR::Type *type)
Definition structInitializers.cpp:26
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:51
Collect information related to P4 programs targeting dpdk.
Definition dpdkProgramStructure.h:16
bool is() const noexcept
Definition rtti.h:216