P4C
The P4 Compiler
 
Loading...
Searching...
No Matches
helpers.h
1/*
2Copyright 2013-present Barefoot Networks, Inc.
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_BMV2_COMMON_HELPERS_H_
18#define BACKENDS_BMV2_COMMON_HELPERS_H_
19
20#include "JsonObjects.h"
21#include "controlFlowGraph.h"
22#include "expression.h"
23#include "frontends/common/model.h"
24#include "frontends/p4/fromv1.0/v1model.h"
25#include "ir/ir.h"
26#include "lib/cstring.h"
27#include "lib/json.h"
28#include "lib/ordered_map.h"
29#include "programStructure.h"
30
31namespace BMV2 {
32
33#ifndef UNUSED
34#define UNUSED __attribute__((__unused__))
35#endif
36
38 public:
40 static const cstring rangeMatchTypeName;
41 static const cstring optionalMatchTypeName;
42};
43
45 public:
46 static const unsigned defaultTableSize;
47};
48
50 public:
51 static const cstring jsonMetadataParameterName;
52
56 static const cstring validField;
57};
58
59namespace Standard {
60
69enum class Arch { V1MODEL, PSA, V1MODEL2020 };
70
73template <Arch arch>
75
76template <>
77struct ActionProfileTraits<Arch::V1MODEL> {
78 static const cstring name() { return "action profile"; }
79 static const cstring propertyName() {
80 return P4V1::V1Model::instance.tableAttributes.tableImplementation.name;
81 }
82 static const cstring typeName() { return P4V1::V1Model::instance.action_profile.name; }
83 static const cstring sizeParamName() { return "size"; }
84};
85
86template <>
87struct ActionProfileTraits<Arch::V1MODEL2020> : public ActionProfileTraits<Arch::V1MODEL> {};
88
89template <>
90struct ActionProfileTraits<Arch::PSA> {
91 static const cstring name() { return "action profile"; }
92 static const cstring propertyName() { return "implementation"; }
93 static const cstring typeName() { return "ActionProfile"; }
94 static const cstring sizeParamName() { return "size"; }
95};
96
99template <Arch arch>
101
102template <>
103struct ActionSelectorTraits<Arch::V1MODEL> : public ActionProfileTraits<Arch::V1MODEL> {
104 static const cstring name() { return "action selector"; }
105 static const cstring typeName() { return P4V1::V1Model::instance.action_selector.name; }
106};
107
108template <>
109struct ActionSelectorTraits<Arch::V1MODEL2020> : public ActionProfileTraits<Arch::V1MODEL2020> {};
110
111template <>
112struct ActionSelectorTraits<Arch::PSA> : public ActionProfileTraits<Arch::PSA> {
113 static const cstring name() { return "action selector"; }
114 static const cstring typeName() { return "ActionSelector"; }
115};
116
118template <Arch arch>
120
121template <>
122struct RegisterTraits<Arch::V1MODEL> {
123 static const cstring name() { return "register"; }
124 static const cstring typeName() { return P4V1::V1Model::instance.registers.name; }
125 static const cstring sizeParamName() { return "size"; }
126 // the index of the type parameter for the data stored in the register, in
127 // the type parameter list of the extern type declaration
128 static size_t dataTypeParamIdx() { return 0; }
129 static std::optional<size_t> indexTypeParamIdx() { return std::nullopt; }
130};
131
132template <>
133struct RegisterTraits<Arch::V1MODEL2020> : public RegisterTraits<Arch::V1MODEL> {
134 static std::optional<size_t> indexTypeParamIdx() { return 1; }
135};
136
137template <>
138struct RegisterTraits<Arch::PSA> {
139 static const cstring name() { return "register"; }
140 static const cstring typeName() { return "Register"; }
141 static const cstring sizeParamName() { return "size"; }
142 static size_t dataTypeParamIdx() { return 0; }
143 // the index of the type parameter for the register index, in the type
144 // parameter list of the extern type declaration.
145 static std::optional<size_t> indexTypeParamIdx() { return 1; }
146};
147
148template <Arch arch>
150template <Arch arch>
151struct MeterExtern {};
152
153} // namespace Standard
154
155namespace Helpers {
156
157template <typename Kind>
159
160// According to the C++11 standard: An explicit specialization shall be declared
161// in a namespace enclosing the specialized template. An explicit specialization
162// whose declarator-id is not qualified shall be declared in the nearest
163// enclosing namespace of the template, or, if the namespace is inline (7.3.1),
164// any namespace from its enclosing namespace set. Such a declaration may also
165// be a definition. If the declaration is not a definition, the specialization
166// may be defined later (7.3.1.2).
167//
168// gcc reports an error when trying so specialize CounterlikeTraits<> for
169// Standard::CounterExtern & Standard::MeterExtern outside of the Helpers
170// namespace, even when qualifying CounterlikeTraits<> with Helpers::. It seems
171// to be related to this bug:
172// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480.
173
175template <>
176struct CounterlikeTraits<Standard::CounterExtern<Standard::Arch::V1MODEL>> {
177 static const cstring name() { return "counter"; }
178 static const cstring directPropertyName() {
179 return P4V1::V1Model::instance.tableAttributes.counters.name;
180 }
181 static const cstring typeName() { return P4V1::V1Model::instance.counter.name; }
182 static const cstring directTypeName() { return P4V1::V1Model::instance.directCounter.name; }
183 static const cstring sizeParamName() { return "size"; }
184 static std::optional<size_t> indexTypeParamIdx() { return std::nullopt; }
185};
186
187template <>
188struct CounterlikeTraits<Standard::CounterExtern<Standard::Arch::V1MODEL2020>> {
189 static const cstring name() { return "counter"; }
190 static const cstring directPropertyName() {
191 return P4V1::V1Model::instance.tableAttributes.counters.name;
192 }
193 static const cstring typeName() { return P4V1::V1Model::instance.counter.name; }
194 static const cstring directTypeName() { return P4V1::V1Model::instance.directCounter.name; }
195 static const cstring sizeParamName() { return "size"; }
196 static std::optional<size_t> indexTypeParamIdx() { return 0; }
197};
198
200template <>
201struct CounterlikeTraits<Standard::CounterExtern<Standard::Arch::PSA>> {
202 static const cstring name() { return "counter"; }
203 static const cstring directPropertyName() { return "psa_direct_counter"; }
204 static const cstring typeName() { return "Counter"; }
205 static const cstring directTypeName() { return "DirectCounter"; }
206 static const cstring sizeParamName() { return "n_counters"; }
207 // the index of the type parameter for the counter index, in the type
208 // parameter list of the extern type declaration.
209 static std::optional<size_t> indexTypeParamIdx() { return 1; }
210};
211
213template <>
214struct CounterlikeTraits<Standard::MeterExtern<Standard::Arch::V1MODEL>> {
215 static const cstring name() { return "meter"; }
216 static const cstring directPropertyName() {
217 return P4V1::V1Model::instance.tableAttributes.meters.name;
218 }
219 static const cstring typeName() { return P4V1::V1Model::instance.meter.name; }
220 static const cstring directTypeName() { return P4V1::V1Model::instance.directMeter.name; }
221 static const cstring sizeParamName() { return "size"; }
222 static std::optional<size_t> indexTypeParamIdx() { return std::nullopt; }
223};
224
225template <>
226struct CounterlikeTraits<Standard::MeterExtern<Standard::Arch::V1MODEL2020>> {
227 static const cstring name() { return "meter"; }
228 static const cstring directPropertyName() {
229 return P4V1::V1Model::instance.tableAttributes.meters.name;
230 }
231 static const cstring typeName() { return P4V1::V1Model::instance.meter.name; }
232 static const cstring directTypeName() { return P4V1::V1Model::instance.directMeter.name; }
233 static const cstring sizeParamName() { return "size"; }
234 static std::optional<size_t> indexTypeParamIdx() { return 0; }
235};
236
238template <>
239struct CounterlikeTraits<Standard::MeterExtern<Standard::Arch::PSA>> {
240 static const cstring name() { return "meter"; }
241 static const cstring directPropertyName() { return "psa_direct_meter"; }
242 static const cstring typeName() { return "Meter"; }
243 static const cstring directTypeName() { return "DirectMeter"; }
244 static const cstring sizeParamName() { return "n_meters"; }
245 // the index of the type parameter for the meter index, in the type
246 // parameter list of the extern type declaration.
247 static std::optional<size_t> indexTypeParamIdx() { return 0; }
248};
249
250} // namespace Helpers
251
252using BlockTypeMap = std::map<const IR::Block *, const IR::Type *>;
253
254// XXX(hanw): This convenience class stores pointers to the data structures
255// that are commonly used during the program translation. Due to the limitation
256// of current IR structure, these data structure are only refreshed by the
257// evaluator pass. In the long term, integrating these data structures as part
258// of the IR tree would simplify this kind of bookkeeping effort.
259using SelectorInput = std::vector<const IR::Expression *>;
260
262 // context
263 P4::ReferenceMap *refMap;
264 P4::TypeMap *typeMap;
265 const IR::ToplevelBlock *toplevel;
266 // Block currently being converted
267 BlockConverted blockConverted;
268 //
269 ProgramStructure *structure;
270 // expression converter is used in many places.
272 // final json output.
273 BMV2::JsonObjects *json;
274
275 // for action profile conversion
276 Util::JsonArray *action_profiles = nullptr;
277
278 std::map<const IR::Declaration_Instance *, SelectorInput> selector_input_map;
279
280 const SelectorInput *get_selector_input(const IR::Declaration_Instance *selector) {
281 auto it = selector_input_map.find(selector);
282 if (it == selector_input_map.end()) return nullptr; // selector never used
283 return &it->second;
284 }
285
287 const IR::ToplevelBlock *toplevel, ProgramStructure *structure,
288 ExpressionConverter *conv, JsonObjects *json)
289 : refMap(refMap),
290 typeMap(typeMap),
291 toplevel(toplevel),
292 blockConverted(BlockConverted::None),
293 structure(structure),
294 conv(conv),
295 json(json) {}
296
297 void addToFieldList(const IR::Expression *expr, Util::JsonArray *fl);
298 int createFieldList(const IR::Expression *expr, cstring listName, bool learn = false);
299 cstring createCalculation(cstring algo, const IR::Expression *fields,
300 Util::JsonArray *calculations, bool usePayload, const IR::Node *node);
301 static void modelError(const char *format, const IR::Node *place);
302};
303
304Util::IJson *nodeName(const CFG::Node *node);
305Util::JsonArray *mkArrayField(Util::JsonObject *parent, cstring name);
306Util::JsonArray *mkParameters(Util::JsonObject *object);
308Util::JsonObject *mkPrimitive(cstring name);
309cstring stringRepr(big_int value, unsigned bytes = 0);
310unsigned nextId(cstring group);
312const IR::ListExpression *convertToList(const IR::Expression *expr, P4::TypeMap *typeMap);
313
314} // namespace BMV2
315
316#endif /* BACKENDS_BMV2_COMMON_HELPERS_H_ */
Definition controlFlowGraph.h:60
Definition expression.h:53
Definition JsonObjects.h:27
Definition helpers.h:37
static const cstring selectorMatchTypeName
constant definition for bmv2
Definition helpers.h:39
Definition programStructure.h:40
Definition sharedActionSelectorCheck.h:40
Definition helpers.h:44
Definition helpers.h:49
static const cstring validField
Definition helpers.h:56
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Definition typeMap.h:42
Definition json.h:40
Definition json.h:111
Definition json.h:158
Definition cstring.h:72
Definition helpers.h:261
Definition helpers.h:158
Definition helpers.h:100
Definition helpers.h:149
Definition helpers.h:151
Traits for the register extern, must be specialized for v1model and PSA.
Definition helpers.h:119