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 DPDK {
39
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 P4::ReferenceMap *refMap;
121 P4::TypeMap *typeMap;
122 bool nested(const IR::Node *n) {
123 if (n->is<IR::LAnd>() || n->is<IR::LOr>()) {
124 return true;
125 } else {
126 return false;
127 }
128 }
129
130 public:
131 IR::IndexedVector<IR::DpdkAsmStatement> instructions;
133 : refMap(refMap), typeMap(typeMap) {}
134 bool generate(const IR::Expression *, cstring, cstring, bool);
135};
136
137class TypeWidthValidator : public Inspector {
138 void postorder(const IR::Type_Varbits *type) override {
139 LOG3("Validating Type_Varbits: " << type);
140 if (type->size % 8 != 0) {
141 ::error(ErrorType::ERR_UNSUPPORTED, "%1% varbit width (%2%) not aligned to 8 bits",
142 type->srcInfo, type->size);
143 }
144 }
145};
146
147class ConvertStatementToDpdk : public Inspector {
148 IR::IndexedVector<IR::DpdkAsmStatement> instructions;
149 P4::TypeMap *typemap;
150 P4::ReferenceMap *refmap;
151 DpdkProgramStructure *structure;
152 const IR::P4Parser *parser = nullptr;
153 const IR::Node *parent = nullptr;
154 IR::Type_Struct *metadataStruct = nullptr;
155
156 private:
157 void processHashParams(const IR::Argument *field, IR::Vector<IR::Expression> &components);
158 bool checkIfBelongToSameHdrMdStructure(const IR::Argument *field);
159 void updateMdStrAndGenInstr(const IR::Argument *field, IR::Vector<IR::Expression> &components);
160 cstring getHdrMdStrName(const IR::Member *mem);
161 bool checkIfConsecutiveHdrMdfields(const IR::Argument *field);
162
163 public:
165 DpdkProgramStructure *structure)
166 : typemap(typemap), refmap(refmap), structure(structure) {
167 visitDagOnce = false;
168 }
170 DpdkProgramStructure *structure, IR::Type_Struct *metadataStruct)
171 : typemap(typemap), refmap(refmap), structure(structure), metadataStruct(metadataStruct) {
172 visitDagOnce = false;
173 }
174 IR::IndexedVector<IR::DpdkAsmStatement> getInstructions() { return instructions; }
175 void branchingInstructionGeneration(cstring true_label, cstring false_label,
176 const IR::Expression *expr);
177 bool preorder(const IR::AssignmentStatement *a) override;
178 bool preorder(const IR::IfStatement *a) override;
179 bool preorder(const IR::MethodCallStatement *a) override;
180 bool preorder(const IR::SwitchStatement *a) override;
181
182 void add_instr(const IR::DpdkAsmStatement *s) { instructions.push_back(s); }
183 IR::IndexedVector<IR::DpdkAsmStatement> &get_instr() { return instructions; }
184 void process_logical_operation(const IR::Expression *, const IR::Operation_Binary *);
185 void process_relation_operation(const IR::Expression *, const IR::Operation_Relation *);
186 cstring append_parser_name(const IR::P4Parser *p, cstring);
187 void set_parser(const IR::P4Parser *p) { parser = p; }
188 void set_parent(const IR::Node *p) { parent = p; }
189 bool handleConstSwitch(const IR::SwitchStatement *a);
190};
191
196 const std::set<cstring> *process;
197
198 public:
199 explicit ProcessControls(const std::set<cstring> *process) : process(process) {
200 CHECK_NULL(process);
201 }
202 bool convert(const IR::P4Control *control) const {
203 if (process->find(control->name) != process->end()) return true;
204 return false;
205 }
206};
207
208} // namespace DPDK
209#endif /* BACKENDS_DPDK_DPDKHELPERS_H_ */
Definition dpdkHelpers.h:119
Definition dpdkHelpers.h:147
Definition dpdkHelpers.h:195
bool convert(const IR::P4Control *control) const
Definition dpdkHelpers.h:202
Definition dpdkHelpers.h:137
Definition externInstance.h:33
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Definition removeComplexExpressions.h:30
Definition typeMap.h:42
Definition cstring.h:72
Definition backend.cpp:35
const char PnaMainOutputMetadataOutputPortName[]
Name of the metadata used as output port.
Definition dpdkHelpers.h:50
Definition dpdkProgramStructure.h:14