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