P4C
The P4 Compiler
Loading...
Searching...
No Matches
p4RuntimeArchStandard.h
1/*
2 * SPDX-FileCopyrightText: 2018 Barefoot Networks, Inc.
3 * Copyright 2018-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef CONTROL_PLANE_P4RUNTIMEARCHSTANDARD_H_
9#define CONTROL_PLANE_P4RUNTIMEARCHSTANDARD_H_
10
11#include "frontends/common/resolveReferences/referenceMap.h"
12#include "frontends/p4-14/fromv1.0/v1model.h"
13#include "frontends/p4/typeMap.h"
14#include "ir/ir.h"
15#include "p4RuntimeArchHandler.h"
16
17namespace p4configv1 = ::p4::config::v1;
18
20using ::P4::ControlPlaneAPI::Helpers::setPreamble;
21
22namespace P4 {
23
27namespace ControlPlaneAPI {
28
29namespace Standard {
30
38enum class Arch { V1MODEL, PSA, PNA, V1MODEL2020 };
39
40template <Arch arch>
41struct CounterExtern {};
42template <Arch arch>
43struct MeterExtern {};
44
45} // namespace Standard
46
47namespace Helpers {
48
49// According to the C++11 standard: An explicit specialization shall be declared
50// in a namespace enclosing the specialized template. An explicit specialization
51// whose declarator-id is not qualified shall be declared in the nearest
52// enclosing namespace of the template, or, if the namespace is inline (7.3.1),
53// any namespace from its enclosing namespace set. Such a declaration may also
54// be a definition. If the declaration is not a definition, the specialization
55// may be defined later (7.3.1.2).
56//
57// GCC reports an error when trying so specialize CounterlikeTraits<> for
58// Standard::CounterExtern & Standard::MeterExtern outside of the Helpers
59// namespace, even when qualifying CounterlikeTraits<> with Helpers::. It seems
60// to be related to this bug:
61// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480.
62
64template <>
65struct CounterlikeTraits<Standard::CounterExtern<Standard::Arch::V1MODEL>> {
66 static const cstring name() { return "counter"_cs; }
67 static const cstring directPropertyName() {
68 return P4V1::V1Model::instance.tableAttributes.counters.name;
69 }
70 static const cstring typeName() { return P4V1::V1Model::instance.counter.name; }
71 static const cstring directTypeName() { return P4V1::V1Model::instance.directCounter.name; }
72 static const cstring sizeParamName() { return "size"_cs; }
73 static p4configv1::CounterSpec::Unit mapUnitName(const cstring name) {
74 using p4configv1::CounterSpec;
75 if (name == "packets")
76 return CounterSpec::PACKETS;
77 else if (name == "bytes")
78 return CounterSpec::BYTES;
79 else if (name == "packets_and_bytes")
80 return CounterSpec::BOTH;
81 return CounterSpec::UNSPECIFIED;
82 }
83 static std::optional<size_t> indexTypeParamIdx() { return std::nullopt; }
84};
85
86template <>
87struct CounterlikeTraits<Standard::CounterExtern<Standard::Arch::V1MODEL2020>> {
88 static const cstring name() { return "counter"_cs; }
89 static const cstring directPropertyName() {
90 return P4V1::V1Model::instance.tableAttributes.counters.name;
91 }
92 static const cstring typeName() { return P4V1::V1Model::instance.counter.name; }
93 static const cstring directTypeName() { return P4V1::V1Model::instance.directCounter.name; }
94 static const cstring sizeParamName() { return "size"_cs; }
95 static p4configv1::CounterSpec::Unit mapUnitName(const cstring name) {
96 using p4configv1::CounterSpec;
97 if (name == "packets")
98 return CounterSpec::PACKETS;
99 else if (name == "bytes")
100 return CounterSpec::BYTES;
101 else if (name == "packets_and_bytes")
102 return CounterSpec::BOTH;
103 return CounterSpec::UNSPECIFIED;
104 }
105 static std::optional<size_t> indexTypeParamIdx() { return 0; }
106};
107
109template <>
110struct CounterlikeTraits<Standard::CounterExtern<Standard::Arch::PSA>> {
111 static const cstring name() { return "counter"_cs; }
112 static const cstring directPropertyName() { return "psa_direct_counter"_cs; }
113 static const cstring typeName() { return "Counter"_cs; }
114 static const cstring directTypeName() { return "DirectCounter"_cs; }
115 static const cstring sizeParamName() { return "n_counters"_cs; }
116 static p4configv1::CounterSpec::Unit mapUnitName(const cstring name) {
117 using p4configv1::CounterSpec;
118 if (name == "PACKETS")
119 return CounterSpec::PACKETS;
120 else if (name == "BYTES")
121 return CounterSpec::BYTES;
122 else if (name == "PACKETS_AND_BYTES")
123 return CounterSpec::BOTH;
124 return CounterSpec::UNSPECIFIED;
125 }
126 // the index of the type parameter for the counter index, in the type
127 // parameter list of the extern type declaration.
128 static std::optional<size_t> indexTypeParamIdx() { return 1; }
129};
130
132template <>
133struct CounterlikeTraits<Standard::CounterExtern<Standard::Arch::PNA>> {
134 static const cstring name() { return "counter"_cs; }
135 static const cstring directPropertyName() { return "pna_direct_counter"_cs; }
136 static const cstring typeName() { return "Counter"_cs; }
137 static const cstring directTypeName() { return "DirectCounter"_cs; }
138 static const cstring sizeParamName() { return "n_counters"_cs; }
139 static p4configv1::CounterSpec::Unit mapUnitName(const cstring name) {
140 using p4configv1::CounterSpec;
141 if (name == "PACKETS")
142 return CounterSpec::PACKETS;
143 else if (name == "BYTES")
144 return CounterSpec::BYTES;
145 else if (name == "PACKETS_AND_BYTES")
146 return CounterSpec::BOTH;
147 return CounterSpec::UNSPECIFIED;
148 }
149 // the index of the type parameter for the counter index, in the type
150 // parameter list of the extern type declaration.
151 static std::optional<size_t> indexTypeParamIdx() { return 1; }
152};
153
155template <>
156struct CounterlikeTraits<Standard::MeterExtern<Standard::Arch::V1MODEL>> {
157 static const cstring name() { return "meter"_cs; }
158 static const cstring directPropertyName() {
159 return P4V1::V1Model::instance.tableAttributes.meters.name;
160 }
161 static const cstring typeName() { return P4V1::V1Model::instance.meter.name; }
162 static const cstring directTypeName() { return P4V1::V1Model::instance.directMeter.name; }
163 static const cstring sizeParamName() { return "size"_cs; }
164 static p4configv1::MeterSpec::Unit mapUnitName(const cstring name) {
165 using p4configv1::MeterSpec;
166 if (name == "packets")
167 return MeterSpec::PACKETS;
168 else if (name == "bytes")
169 return MeterSpec::BYTES;
170 return MeterSpec::UNSPECIFIED;
171 }
172 static std::optional<size_t> indexTypeParamIdx() { return std::nullopt; }
173};
174
175template <>
176struct CounterlikeTraits<Standard::MeterExtern<Standard::Arch::V1MODEL2020>> {
177 static const cstring name() { return "meter"_cs; }
178 static const cstring directPropertyName() {
179 return P4V1::V1Model::instance.tableAttributes.meters.name;
180 }
181 static const cstring typeName() { return P4V1::V1Model::instance.meter.name; }
182 static const cstring directTypeName() { return P4V1::V1Model::instance.directMeter.name; }
183 static const cstring sizeParamName() { return "size"_cs; }
184 static p4configv1::MeterSpec::Unit mapUnitName(const cstring name) {
185 using p4configv1::MeterSpec;
186 if (name == "packets")
187 return MeterSpec::PACKETS;
188 else if (name == "bytes")
189 return MeterSpec::BYTES;
190 return MeterSpec::UNSPECIFIED;
191 }
192 static std::optional<size_t> indexTypeParamIdx() { return 0; }
193};
194
196template <>
197struct CounterlikeTraits<Standard::MeterExtern<Standard::Arch::PSA>> {
198 static const cstring name() { return "meter"_cs; }
199 static const cstring directPropertyName() { return "psa_direct_meter"_cs; }
200 static const cstring typeName() { return "Meter"_cs; }
201 static const cstring directTypeName() { return "DirectMeter"_cs; }
202 static const cstring sizeParamName() { return "n_meters"_cs; }
203 static p4configv1::MeterSpec::Unit mapUnitName(const cstring name) {
204 using p4configv1::MeterSpec;
205 if (name == "PACKETS")
206 return MeterSpec::PACKETS;
207 else if (name == "BYTES")
208 return MeterSpec::BYTES;
209 return MeterSpec::UNSPECIFIED;
210 }
211 // the index of the type parameter for the meter index, in the type
212 // parameter list of the extern type declaration.
213 static std::optional<size_t> indexTypeParamIdx() { return 0; }
214};
215
217template <>
218struct CounterlikeTraits<Standard::MeterExtern<Standard::Arch::PNA>> {
219 static const cstring name() { return "meter"_cs; }
220 static const cstring directPropertyName() { return "pna_direct_meter"_cs; }
221 static const cstring typeName() { return "Meter"_cs; }
222 static const cstring directTypeName() { return "DirectMeter"_cs; }
223 static const cstring sizeParamName() { return "n_meters"_cs; }
224 static p4configv1::MeterSpec::Unit mapUnitName(const cstring name) {
225 using p4configv1::MeterSpec;
226 if (name == "PACKETS")
227 return MeterSpec::PACKETS;
228 else if (name == "BYTES")
229 return MeterSpec::BYTES;
230 return MeterSpec::UNSPECIFIED;
231 }
232 // the index of the type parameter for the meter index, in the type
233 // parameter list of the extern type declaration.
234 static std::optional<size_t> indexTypeParamIdx() { return 0; }
235};
236
237} // namespace Helpers
238
240namespace Standard {
241
245 const IR::ToplevelBlock *evaluatedProgram) const override;
246};
247
251 const IR::ToplevelBlock *evaluatedProgram) const override;
252};
253
257 const IR::ToplevelBlock *evaluatedProgram) const override;
258};
259
263 const IR::ToplevelBlock *evaluatedProgram) const override;
264};
265
268class SymbolType : public P4RuntimeSymbolType {
269 public:
270 SymbolType() = delete;
271
272 static P4RuntimeSymbolType P4RT_ACTION_PROFILE() {
273 return P4RuntimeSymbolType::make(p4configv1::P4Ids::ACTION_PROFILE);
274 }
275 static P4RuntimeSymbolType P4RT_COUNTER() {
276 return P4RuntimeSymbolType::make(p4configv1::P4Ids::COUNTER);
277 }
278 static P4RuntimeSymbolType P4RT_DIGEST() {
279 return P4RuntimeSymbolType::make(p4configv1::P4Ids::DIGEST);
280 }
281 static P4RuntimeSymbolType P4RT_DIRECT_COUNTER() {
282 return P4RuntimeSymbolType::make(p4configv1::P4Ids::DIRECT_COUNTER);
283 }
284 static P4RuntimeSymbolType P4RT_DIRECT_METER() {
285 return P4RuntimeSymbolType::make(p4configv1::P4Ids::DIRECT_METER);
286 }
287 static P4RuntimeSymbolType P4RT_METER() {
288 return P4RuntimeSymbolType::make(p4configv1::P4Ids::METER);
289 }
290 static P4RuntimeSymbolType P4RT_REGISTER() {
291 return P4RuntimeSymbolType::make(p4configv1::P4Ids::REGISTER);
292 }
293};
294
297template <Arch arch>
299
300template <>
301struct ActionProfileTraits<Arch::V1MODEL> {
302 static const cstring name() { return "action profile"_cs; }
303 static const cstring propertyName() {
304 return P4V1::V1Model::instance.tableAttributes.tableImplementation.name;
305 }
306 static const cstring typeName() { return P4V1::V1Model::instance.action_profile.name; }
307 static const cstring sizeParamName() { return "size"_cs; }
308};
309
310template <>
311struct ActionProfileTraits<Arch::V1MODEL2020> {
312 static const cstring name() { return "action profile"_cs; }
313 static const cstring propertyName() {
314 return P4V1::V1Model::instance.tableAttributes.tableImplementation.name;
315 }
316 static const cstring typeName() { return P4V1::V1Model::instance.action_profile.name; }
317 static const cstring sizeParamName() { return "size"_cs; }
318};
319
320template <>
322 static const cstring name() { return "action profile"_cs; }
323 static const cstring propertyName() { return "psa_implementation"_cs; }
324 static const cstring typeName() { return "ActionProfile"_cs; }
325 static const cstring sizeParamName() { return "size"_cs; }
326};
327
328template <>
330 static const cstring name() { return "action profile"_cs; }
331 static const cstring propertyName() { return "pna_implementation"_cs; }
332 static const cstring typeName() { return "ActionProfile"_cs; }
333 static const cstring sizeParamName() { return "size"_cs; }
334};
335
338template <Arch arch>
340
341template <>
342struct ActionSelectorTraits<Arch::V1MODEL> : public ActionProfileTraits<Arch::V1MODEL> {
343 static const cstring name() { return "action selector"_cs; }
344 static const cstring typeName() { return P4V1::V1Model::instance.action_selector.name; }
345};
346
347template <>
348struct ActionSelectorTraits<Arch::V1MODEL2020> : public ActionProfileTraits<Arch::V1MODEL2020> {
349 static const cstring name() { return "action selector"_cs; }
350 static const cstring typeName() { return P4V1::V1Model::instance.action_selector.name; }
351};
352
353template <>
354struct ActionSelectorTraits<Arch::PSA> : public ActionProfileTraits<Arch::PSA> {
355 static const cstring name() { return "action selector"_cs; }
356 static const cstring typeName() { return "ActionSelector"_cs; }
357};
358
359template <>
360struct ActionSelectorTraits<Arch::PNA> : public ActionProfileTraits<Arch::PNA> {
361 static const cstring name() { return "action selector"_cs; }
362 static const cstring typeName() { return "ActionSelector"_cs; }
363};
364
366template <Arch arch>
368
369template <>
370struct RegisterTraits<Arch::V1MODEL> {
371 static const cstring name() { return "register"_cs; }
372 static const cstring typeName() { return P4V1::V1Model::instance.registers.name; }
373 static const cstring sizeParamName() { return "size"_cs; }
374 // the index of the type parameter for the data stored in the register, in
375 // the type parameter list of the extern type declaration
376 static size_t dataTypeParamIdx() { return 0; }
377 static std::optional<size_t> indexTypeParamIdx() { return std::nullopt; }
378};
379
380template <>
381struct RegisterTraits<Arch::V1MODEL2020> {
382 static const cstring name() { return "register"_cs; }
383 static const cstring typeName() { return P4V1::V1Model::instance.registers.name; }
384 static const cstring sizeParamName() { return "size"_cs; }
385 // the index of the type parameter for the data stored in the register, in
386 // the type parameter list of the extern type declaration
387 static size_t dataTypeParamIdx() { return 0; }
388 static std::optional<size_t> indexTypeParamIdx() { return 1; }
389};
390
391template <>
392struct RegisterTraits<Arch::PSA> {
393 static const cstring name() { return "register"_cs; }
394 static const cstring typeName() { return "Register"_cs; }
395 static const cstring sizeParamName() { return "size"_cs; }
396 static size_t dataTypeParamIdx() { return 0; }
397 // the index of the type parameter for the register index, in the type
398 // parameter list of the extern type declaration.
399 static std::optional<size_t> indexTypeParamIdx() { return 1; }
400};
401
402template <>
403struct RegisterTraits<Arch::PNA> {
404 static const cstring name() { return "register"_cs; }
405 static const cstring typeName() { return "Register"_cs; }
406 static const cstring sizeParamName() { return "size"_cs; }
407 static size_t dataTypeParamIdx() { return 0; }
408 // the index of the type parameter for the register index, in the type
409 // parameter list of the extern type declaration.
410 static std::optional<size_t> indexTypeParamIdx() { return 1; }
411};
412
414struct Digest {
415 const cstring name; // The fully qualified external name of the digest
416 // *data* - in P4-14, the field list name, or in
417 // P4-16, the type of the 'data' parameter.
418 const p4configv1::P4DataTypeSpec *typeSpec; // The format of the packed data.
419 const IR::IAnnotated *annotations; // If non-null, any annotations applied to this digest
420 // declaration.
421};
422
423struct Register {
424 const cstring name; // The fully qualified external name of this register.
425 const IR::IAnnotated *annotations; // If non-null, any annotations applied
426 // to this field.
427 const int64_t size;
428 const p4configv1::P4DataTypeSpec *typeSpec; // The format of the stored data.
429 // If the type of the index is a user-defined type, this is the name of the type. Otherwise it
430 // is nullptr.
431 const cstring index_type_name;
432
435 template <Arch arch>
436 static std::optional<Register> from(const IR::ExternBlock *instance, const ReferenceMap *refMap,
437 P4::TypeMap *typeMap,
438 p4configv1::P4TypeInfo *p4RtTypeInfo) {
439 CHECK_NULL(instance);
440 auto declaration = instance->node->to<IR::Declaration_Instance>();
441
442 auto size = instance->getParameterValue("size"_cs)->to<IR::Constant>();
443 if (!size->is<IR::Constant>()) {
444 ::P4::error(ErrorType::ERR_UNSUPPORTED, "Register '%1%' has a non-constant size: %2%",
445 declaration, size);
446 return std::nullopt;
447 }
448 if (!size->to<IR::Constant>()->fitsInt()) {
449 ::P4::error(ErrorType::ERR_UNSUPPORTED,
450 "Register '%1%' has a size that doesn't fit in an integer: %2%",
451 declaration, size);
452 return std::nullopt;
453 }
454
455 // retrieve type parameter for the register instance and convert it to P4DataTypeSpec
456 BUG_CHECK(declaration->type->is<IR::Type_Specialized>(), "%1%: expected Type_Specialized",
457 declaration->type);
458 auto type = declaration->type->to<IR::Type_Specialized>();
459 auto typeParamIdx = RegisterTraits<arch>::dataTypeParamIdx();
460 BUG_CHECK(type->arguments->size() > typeParamIdx,
461 "%1%: expected at least %2% type arguments", instance, typeParamIdx + 1);
462 auto typeArg = type->arguments->at(typeParamIdx);
463 auto typeSpec = TypeSpecConverter::convert(refMap, typeMap, typeArg, p4RtTypeInfo);
464 CHECK_NULL(typeSpec);
465
466 cstring index_type_name = nullptr;
467 auto indexTypeParamIdx = RegisterTraits<arch>::indexTypeParamIdx();
468 // In v1model, the index is a bit<32>, in PSA it is determined by a type parameter.
469 if (indexTypeParamIdx != std::nullopt) {
470 // retrieve type parameter for the index.
471 BUG_CHECK(declaration->type->is<IR::Type_Specialized>(),
472 "%1%: expected Type_Specialized", declaration->type);
473 auto type = declaration->type->to<IR::Type_Specialized>();
474 BUG_CHECK(type->arguments->size() > *indexTypeParamIdx,
475 "%1%: expected at least %2% type arguments", instance,
476 *indexTypeParamIdx + 1);
477 auto typeArg = type->arguments->at(*indexTypeParamIdx);
478 // We ignore the return type on purpose, but the call is required to update p4RtTypeInfo
479 // if the index has a user-defined type.
480 TypeSpecConverter::convert(refMap, typeMap, typeArg, p4RtTypeInfo);
481 index_type_name = getTypeName(typeArg, typeMap);
482 }
483
484 return Register{declaration->controlPlaneName(), declaration->to<IR::IAnnotated>(),
485 int(size->value), typeSpec, index_type_name};
486 }
487};
488
490enum class ActionProfileType { INDIRECT, INDIRECT_WITH_SELECTOR };
491
495 const cstring name; // The fully qualified external name of this action profile.
496 const ActionProfileType type;
497 const int64_t size;
498 const IR::IAnnotated *annotations; // If non-null, any annotations applied to this action
499 // profile declaration.
500
501 bool operator<(const ActionProfile &other) const {
502 if (name != other.name) return name < other.name;
503 if (type != other.type) return type < other.type;
504 return size < other.size;
505 }
506};
507
513template <Arch arch>
514class P4RuntimeArchHandlerCommon : public P4RuntimeArchHandlerIface {
515 protected:
516 using ArchCounterExtern = CounterExtern<arch>;
518 using ArchMeterExtern = MeterExtern<arch>;
520
521 using Counter = p4configv1::Counter;
522 using Meter = p4configv1::Meter;
523 using CounterSpec = p4configv1::CounterSpec;
524 using MeterSpec = p4configv1::MeterSpec;
525
526 P4RuntimeArchHandlerCommon(ReferenceMap *refMap, TypeMap *typeMap,
527 const IR::ToplevelBlock *evaluatedProgram)
528 : refMap(refMap), typeMap(typeMap), evaluatedProgram(evaluatedProgram) {
529 jsonPrintOptions.add_whitespace = true;
530 }
531
533 const IR::TableBlock *tableBlock) override {
534 CHECK_NULL(tableBlock);
535 auto table = tableBlock->container;
536 bool isConstructedInPlace = false;
537
538 {
539 auto instance =
540 getExternInstanceFromProperty(table, ActionProfileTraits<arch>::propertyName(),
541 refMap, typeMap, &isConstructedInPlace);
542 if (instance) {
543 if (instance->type->name != ActionProfileTraits<arch>::typeName() &&
544 instance->type->name != ActionSelectorTraits<arch>::typeName()) {
545 ::P4::error(ErrorType::ERR_EXPECTED,
546 "Expected an action profile or action selector: %1%",
547 instance->expression);
548 } else if (isConstructedInPlace) {
549 symbols->add(SymbolType::P4RT_ACTION_PROFILE(), *instance->name);
550 }
551 }
552 }
553 {
554 auto instance = getExternInstanceFromProperty(
555 table, CounterTraits::directPropertyName(), refMap, typeMap, &isConstructedInPlace);
556 if (instance) {
557 if (instance->type->name != CounterTraits::directTypeName()) {
558 ::P4::error(ErrorType::ERR_EXPECTED, "Expected a direct counter: %1%",
559 instance->expression);
560 } else if (isConstructedInPlace) {
561 symbols->add(SymbolType::P4RT_DIRECT_COUNTER(), *instance->name);
562 }
563 }
564 }
565 {
566 auto instance = getExternInstanceFromProperty(table, MeterTraits::directPropertyName(),
567 refMap, typeMap, &isConstructedInPlace);
568 if (instance) {
569 if (instance->type->name != MeterTraits::directTypeName()) {
570 ::P4::error(ErrorType::ERR_EXPECTED, "Expected a direct meter: %1%",
571 instance->expression);
572 } else if (isConstructedInPlace) {
573 symbols->add(SymbolType::P4RT_DIRECT_METER(), *instance->name);
574 }
575 }
576 }
577 }
578
580 const IR::BaseAssignmentStatement *) override {}
581
583
585 const IR::ExternBlock *externBlock) override {
586 CHECK_NULL(externBlock);
587
588 auto decl = externBlock->node->to<IR::IDeclaration>();
589 // Skip externs instantiated inside table declarations (as properties);
590 // that should only apply to action profiles / selectors since direct
591 // resources cannot be constructed in place for PSA.
592 if (decl == nullptr) return;
593
594 if (externBlock->type->name == CounterTraits::typeName()) {
595 symbols->add(SymbolType::P4RT_COUNTER(), decl);
596 } else if (externBlock->type->name == CounterTraits::directTypeName()) {
597 symbols->add(SymbolType::P4RT_DIRECT_COUNTER(), decl);
598 } else if (externBlock->type->name == MeterTraits::typeName()) {
599 symbols->add(SymbolType::P4RT_METER(), decl);
600 } else if (externBlock->type->name == MeterTraits::directTypeName()) {
601 symbols->add(SymbolType::P4RT_DIRECT_METER(), decl);
602 } else if (externBlock->type->name == ActionProfileTraits<arch>::typeName() ||
603 externBlock->type->name == ActionSelectorTraits<arch>::typeName()) {
604 symbols->add(SymbolType::P4RT_ACTION_PROFILE(), decl);
605 } else if (externBlock->type->name == RegisterTraits<arch>::typeName()) {
606 symbols->add(SymbolType::P4RT_REGISTER(), decl);
607 }
608 }
609
611 const P4::ExternFunction *externFunction) override {
612 // no common task
613 (void)symbols;
614 (void)externFunction;
615 }
616
617 void collectExtra(P4RuntimeSymbolTableIface *symbols) override {
618 // nothing to do for standard architectures
619 (void)symbols;
620 }
621
622 void postCollect(const P4RuntimeSymbolTableIface &symbols) override {
623 (void)symbols;
624 // analyze action profiles and build a mapping from action profile name
625 // to the set of tables referencing them
626 Helpers::forAllEvaluatedBlocks(evaluatedProgram, [&](const IR::Block *block) {
627 if (!block->is<IR::TableBlock>()) return;
628 auto table = block->to<IR::TableBlock>()->container;
629 auto implementation = getTableImplementationName(table, refMap);
630 if (implementation)
631 actionProfilesRefs[*implementation].insert(table->controlPlaneName());
632 });
633 }
634
635 void addTableProperties(const P4RuntimeSymbolTableIface &symbols, p4configv1::P4Info *p4info,
636 p4configv1::Table *table, const IR::TableBlock *tableBlock) override {
637 CHECK_NULL(tableBlock);
638 auto tableDeclaration = tableBlock->container;
639
641
642 auto implementation = getActionProfile(tableDeclaration, refMap, typeMap);
643 auto directCounter =
644 Helpers::getDirectCounterlike<ArchCounterExtern>(tableDeclaration, refMap, typeMap);
645 auto directMeter =
646 Helpers::getDirectCounterlike<ArchMeterExtern>(tableDeclaration, refMap, typeMap);
647
648 if (implementation) {
649 auto id = symbols.getId(SymbolType::P4RT_ACTION_PROFILE(), implementation->name);
650 table->set_implementation_id(id);
651 auto propertyName = ActionProfileTraits<arch>::propertyName();
652 if (isExternPropertyConstructedInPlace(tableDeclaration, propertyName))
653 addActionProfile(symbols, p4info, *implementation);
654 }
655
656 if (directCounter) {
657 auto id = symbols.getId(SymbolType::P4RT_DIRECT_COUNTER(), directCounter->name);
658 table->add_direct_resource_ids(id);
659 // no risk to add twice because direct counters cannot be shared
660 addCounter(symbols, p4info, *directCounter);
661 }
662
663 if (directMeter) {
664 auto id = symbols.getId(SymbolType::P4RT_DIRECT_METER(), directMeter->name);
665 table->add_direct_resource_ids(id);
666 // no risk to add twice because direct meters cannot be shared
667 addMeter(symbols, p4info, *directMeter);
668 }
669 }
670
671 void addExternInstance(const P4RuntimeSymbolTableIface &symbols, p4configv1::P4Info *p4info,
672 const IR::ExternBlock *externBlock) override {
673 auto decl = externBlock->node->to<IR::Declaration_Instance>();
674 if (decl == nullptr) return;
675
676 auto p4RtTypeInfo = p4info->mutable_type_info();
677 if (externBlock->type->name == CounterTraits::typeName()) {
678 auto counter = Helpers::Counterlike<ArchCounterExtern>::from(externBlock, refMap,
679 typeMap, p4RtTypeInfo);
680 if (counter) addCounter(symbols, p4info, *counter);
681 } else if (externBlock->type->name == MeterTraits::typeName()) {
682 auto meter = Helpers::Counterlike<ArchMeterExtern>::from(externBlock, refMap, typeMap,
683 p4RtTypeInfo);
684 if (meter) addMeter(symbols, p4info, *meter);
685 } else if (externBlock->type->name == RegisterTraits<arch>::typeName()) {
686 auto register_ = Register::from<arch>(externBlock, refMap, typeMap, p4RtTypeInfo);
687 if (register_) addRegister(symbols, p4info, *register_);
688 } else if (externBlock->type->name == ActionProfileTraits<arch>::typeName() ||
689 externBlock->type->name == ActionSelectorTraits<arch>::typeName()) {
690 auto actionProfile = getActionProfile(externBlock);
691 if (actionProfile) addActionProfile(symbols, p4info, *actionProfile);
692 }
693 }
694
695 void addExternFunction(const P4RuntimeSymbolTableIface &, p4configv1::P4Info *,
696 const P4::ExternFunction *) override {}
697
698 void postAdd(const P4RuntimeSymbolTableIface &, ::p4::config::v1::P4Info *) override {}
699
700 void addExternEntries(const p4::v1::WriteRequest *, const P4RuntimeSymbolTableIface &,
701 const IR::ExternBlock *) override {}
702 bool filterAnnotations(cstring) override { return false; }
703
704 google::protobuf::util::JsonPrintOptions getJsonPrintOptions() override {
705 return jsonPrintOptions;
706 }
707
708 static std::optional<ActionProfile> getActionProfile(cstring name, const IR::Type_Extern *type,
709 int64_t size,
710 const IR::IAnnotated *annotations) {
711 ActionProfileType actionProfileType;
712 if (type->name == ActionSelectorTraits<arch>::typeName()) {
713 actionProfileType = ActionProfileType::INDIRECT_WITH_SELECTOR;
714 } else if (type->name == ActionProfileTraits<arch>::typeName()) {
715 actionProfileType = ActionProfileType::INDIRECT;
716 } else {
717 return std::nullopt;
718 }
719
720 return ActionProfile{name, actionProfileType, size, annotations};
721 }
722
725 static std::optional<ActionProfile> getActionProfile(const IR::P4Table *table,
726 ReferenceMap *refMap, TypeMap *typeMap) {
727 auto propertyName = ActionProfileTraits<arch>::propertyName();
728 auto instance = getExternInstanceFromProperty(table, propertyName, refMap, typeMap);
729 if (!instance) return std::nullopt;
730 auto size = instance->substitution.lookupByName(ActionProfileTraits<arch>::sizeParamName())
731 ->expression;
732 if (!size->template is<IR::Constant>()) {
733 ::P4::error(ErrorType::ERR_INVALID, "Action profile '%1%' has non-constant size '%2%'",
734 *instance->name, size);
735 return std::nullopt;
736 }
737 return getActionProfile(*instance->name, instance->type,
738 size->template to<IR::Constant>()->asInt(),
739 getTableImplementationAnnotations(table, refMap));
740 }
741
743 static std::optional<ActionProfile> getActionProfile(const IR::ExternBlock *instance) {
744 auto decl = instance->node->to<IR::IDeclaration>();
745 auto size = instance->getParameterValue(ActionProfileTraits<arch>::sizeParamName());
746 if (!size->template is<IR::Constant>()) {
747 ::P4::error(ErrorType::ERR_INVALID, "Action profile '%1%' has non-constant size '%2%'",
748 decl->controlPlaneName(), size);
749 return std::nullopt;
750 }
751 return getActionProfile(decl->controlPlaneName(), instance->type,
752 size->template to<IR::Constant>()->asInt(),
753 decl->to<IR::IAnnotated>());
754 }
755
756 void addActionProfile(const P4RuntimeSymbolTableIface &symbols, p4configv1::P4Info *p4Info,
757 const ActionProfile &actionProfile) {
758 auto profile = p4Info->add_action_profiles();
759 auto id = symbols.getId(SymbolType::P4RT_ACTION_PROFILE(), actionProfile.name);
760 setPreamble(profile->mutable_preamble(), id, actionProfile.name,
761 symbols.getAlias(actionProfile.name), actionProfile.annotations,
762 // exclude @max_group_size, @selector_size_semantics, and
763 // @max_member_weight if present
764 [](cstring name) {
765 return name == "max_group_size" || name == "selector_size_semantics" ||
766 name == "max_member_weight";
767 });
768 profile->set_with_selector(actionProfile.type == ActionProfileType::INDIRECT_WITH_SELECTOR);
769 profile->set_size(actionProfile.size);
770 auto maxGroupSizeAnnotation = actionProfile.annotations->getAnnotation("max_group_size"_cs);
771 if (maxGroupSizeAnnotation) {
772 if (actionProfile.type == ActionProfileType::INDIRECT_WITH_SELECTOR) {
773 auto maxGroupSizeConstant =
774 maxGroupSizeAnnotation->getExpr(0)->checkedTo<IR::Constant>();
775 CHECK_NULL(maxGroupSizeConstant);
776 profile->set_max_group_size(maxGroupSizeConstant->asInt());
777 } else {
778 ::P4::warning(ErrorType::WARN_IGNORE,
779 "Ignoring annotation @max_group_size on action profile '%1%', "
780 "which does not have a selector",
781 actionProfile.annotations);
782 }
783 }
784
785 // By default, an action profile uses the SumOfWeights semantics.
786 auto selectorSizeSemanticsAnnotation =
787 actionProfile.annotations->getAnnotation("selector_size_semantics"_cs);
788 if (selectorSizeSemanticsAnnotation) {
789 if (actionProfile.type == ActionProfileType::INDIRECT_WITH_SELECTOR) {
790 auto selectorSizeSemantics =
791 selectorSizeSemanticsAnnotation->getExpr(0)->checkedTo<IR::StringLiteral>();
792 CHECK_NULL(selectorSizeSemantics);
793 // The expression may only contain 'sum_of_weights' or 'sum_of_members'
794 // in any case.
795 if (selectorSizeSemantics->value.toUpper() == "SUM_OF_WEIGHTS") {
796 profile->mutable_sum_of_weights();
797 } else if (selectorSizeSemantics->value.toUpper() == "SUM_OF_MEMBERS") {
798 profile->mutable_sum_of_members();
799 } else {
800 ::P4::error(ErrorType::ERR_INVALID,
801 "Expected selector_size_semantics value \"sum_of_weights\" or "
802 "\"sum_of_members\", but got '%1%'",
803 selectorSizeSemantics);
804 }
805 } else {
806 ::P4::warning(ErrorType::WARN_IGNORE,
807 "Ignoring annotation @selector_size_semantics on action "
808 "profile '%1%', which does not have a selector ",
809 actionProfile.annotations);
810 }
811 }
812
813 // By default, an action profile uses the SumOfWeights semantics.
814 auto maxMemberWeightAnnotation =
815 actionProfile.annotations->getAnnotation("max_member_weight"_cs);
816 if (maxMemberWeightAnnotation) {
817 if (actionProfile.type == ActionProfileType::INDIRECT_WITH_SELECTOR &&
818 profile->has_sum_of_members()) {
819 auto maxMemberWeightConstant =
820 maxMemberWeightAnnotation->getExpr(0)->checkedTo<IR::Constant>();
821 CHECK_NULL(maxMemberWeightConstant);
822 profile->mutable_sum_of_members()->set_max_member_weight(
823 maxMemberWeightConstant->asInt());
824 } else if (actionProfile.type != ActionProfileType::INDIRECT_WITH_SELECTOR) {
825 ::P4::warning(ErrorType::WARN_IGNORE,
826 "Ignoring annotation @max_member_weight on action profile "
827 "'%1%', which does not have a selector",
828 actionProfile.annotations);
829 } else {
830 ::P4::warning(ErrorType::WARN_IGNORE,
831 "Ignoring annotation @max_member_weight on action profile '%1%', "
832 "which does not use 'sum_of_members' as its SelectorSizeSemantics",
833 actionProfile.annotations);
834 }
835 }
836
837 auto tablesIt = actionProfilesRefs.find(actionProfile.name);
838 if (tablesIt != actionProfilesRefs.end()) {
839 for (const auto &table : tablesIt->second)
840 profile->add_table_ids(symbols.getId(P4RuntimeSymbolType::P4RT_TABLE(), table));
841 }
842 }
843
845 template <typename Kind>
846 void setCounterCommon(const P4RuntimeSymbolTableIface &symbols, Kind *counter, p4rt_id_t id,
847 const Helpers::Counterlike<ArchCounterExtern> &counterInstance) {
848 setPreamble(counter->mutable_preamble(), id, counterInstance.name,
849 symbols.getAlias(counterInstance.name), counterInstance.annotations);
850 auto counter_spec = counter->mutable_spec();
851 counter_spec->set_unit(CounterTraits::mapUnitName(counterInstance.unit));
852 }
853
854 void addCounter(const P4RuntimeSymbolTableIface &symbols, p4configv1::P4Info *p4Info,
855 const Helpers::Counterlike<ArchCounterExtern> &counterInstance) {
856 if (counterInstance.table) {
857 auto counter = p4Info->add_direct_counters();
858 auto id = symbols.getId(SymbolType::P4RT_DIRECT_COUNTER(), counterInstance.name);
859 setCounterCommon(symbols, counter, id, counterInstance);
860 auto tableId = symbols.getId(P4RuntimeSymbolType::P4RT_TABLE(), *counterInstance.table);
861 counter->set_direct_table_id(tableId);
862 } else {
863 auto counter = p4Info->add_counters();
864 auto id = symbols.getId(SymbolType::P4RT_COUNTER(), counterInstance.name);
865 setCounterCommon(symbols, counter, id, counterInstance);
866 counter->set_size(counterInstance.size);
867 if (counterInstance.index_type_name) {
868 counter->mutable_index_type_name()->set_name(counterInstance.index_type_name);
869 }
870 }
871 }
872
874 template <typename Kind>
875 void setMeterCommon(const P4RuntimeSymbolTableIface &symbols, Kind *meter, p4rt_id_t id,
876 const Helpers::Counterlike<ArchMeterExtern> &meterInstance) {
877 setPreamble(meter->mutable_preamble(), id, meterInstance.name,
878 symbols.getAlias(meterInstance.name), meterInstance.annotations);
879 auto meter_spec = meter->mutable_spec();
880 meter_spec->set_unit(MeterTraits::mapUnitName(meterInstance.unit));
881 }
882
883 void addMeter(const P4RuntimeSymbolTableIface &symbols, p4configv1::P4Info *p4Info,
884 const Helpers::Counterlike<ArchMeterExtern> &meterInstance) {
885 if (meterInstance.table) {
886 auto meter = p4Info->add_direct_meters();
887 auto id = symbols.getId(SymbolType::P4RT_DIRECT_METER(), meterInstance.name);
888 setMeterCommon(symbols, meter, id, meterInstance);
889 auto tableId = symbols.getId(P4RuntimeSymbolType::P4RT_TABLE(), *meterInstance.table);
890 meter->set_direct_table_id(tableId);
891 } else {
892 auto meter = p4Info->add_meters();
893 auto id = symbols.getId(SymbolType::P4RT_METER(), meterInstance.name);
894 setMeterCommon(symbols, meter, id, meterInstance);
895 meter->set_size(meterInstance.size);
896 if (meterInstance.index_type_name) {
897 meter->mutable_index_type_name()->set_name(meterInstance.index_type_name);
898 }
899 }
900 }
901
902 void addRegister(const P4RuntimeSymbolTableIface &symbols, p4configv1::P4Info *p4Info,
903 const Register &registerInstance) {
904 auto register_ = p4Info->add_registers();
905 auto id = symbols.getId(SymbolType::P4RT_REGISTER(), registerInstance.name);
906 setPreamble(register_->mutable_preamble(), id, registerInstance.name,
907 symbols.getAlias(registerInstance.name), registerInstance.annotations);
908 register_->set_size(registerInstance.size);
909 register_->mutable_type_spec()->CopyFrom(*registerInstance.typeSpec);
910 if (registerInstance.index_type_name) {
911 register_->mutable_index_type_name()->set_name(registerInstance.index_type_name);
912 }
913 }
914
915 void addDigest(const P4RuntimeSymbolTableIface &symbols, p4configv1::P4Info *p4Info,
916 const Digest &digest) {
917 // Each call to digest() creates a new digest entry in the P4Info.
918 // Right now we only take the type of data included in the digest
919 // (encoded in its name) into account, but it may be that we should also
920 // consider the receiver.
921 auto id = symbols.getId(SymbolType::P4RT_DIGEST(), digest.name);
922 if (serializedInstances.find(id) != serializedInstances.end()) return;
923 serializedInstances.insert(id);
924
925 auto *digestInstance = p4Info->add_digests();
926 setPreamble(digestInstance->mutable_preamble(), id, digest.name,
927 symbols.getAlias(digest.name), digest.annotations);
928 digestInstance->mutable_type_spec()->CopyFrom(*digest.typeSpec);
929 }
930
933 static const IR::Property *getTableImplementationProperty(const IR::P4Table *table) {
934 return table->properties->getProperty(ActionProfileTraits<arch>::propertyName());
935 }
936
937 static const IR::IAnnotated *getTableImplementationAnnotations(const IR::P4Table *table,
938 ReferenceMap *refMap) {
939 // Cannot use auto here, otherwise the compiler seems to think that the
940 // type of impl is dependent on the template parameter and we run into
941 // this issue: https://stackoverflow.com/a/15572442/4538702
942 const IR::Property *impl = getTableImplementationProperty(table);
943 if (impl == nullptr) return nullptr;
944 if (!impl->value->is<IR::ExpressionValue>()) return nullptr;
945 auto expr = impl->value->to<IR::ExpressionValue>()->expression;
946 if (expr->is<IR::ConstructorCallExpression>()) return impl->to<IR::IAnnotated>();
947 if (expr->is<IR::PathExpression>()) {
948 auto decl = refMap->getDeclaration(expr->to<IR::PathExpression>()->path, true);
949 return decl->to<IR::IAnnotated>();
950 }
951 return nullptr;
952 }
953
954 static std::optional<cstring> getTableImplementationName(const IR::P4Table *table,
955 ReferenceMap *refMap) {
956 const IR::Property *impl = getTableImplementationProperty(table);
957 if (impl == nullptr) return std::nullopt;
958 if (!impl->value->is<IR::ExpressionValue>()) {
960 ErrorType::ERR_EXPECTED,
961 "Expected implementation property value for table %1% to be an expression: %2%",
962 table->controlPlaneName(), impl);
963 return std::nullopt;
964 }
965 auto expr = impl->value->to<IR::ExpressionValue>()->expression;
966 if (expr->is<IR::ConstructorCallExpression>()) return impl->controlPlaneName();
967 if (expr->is<IR::PathExpression>()) {
968 auto decl = refMap->getDeclaration(expr->to<IR::PathExpression>()->path, true);
969 return decl->controlPlaneName();
970 }
971 return std::nullopt;
972 }
973
974 ReferenceMap *refMap;
975 TypeMap *typeMap;
976 const IR::ToplevelBlock *evaluatedProgram;
977
978 std::unordered_map<cstring, std::set<cstring>> actionProfilesRefs;
979
981 std::set<p4rt_id_t> serializedInstances;
982
983 // JSON printing options for serialization
984 google::protobuf::util::JsonPrintOptions jsonPrintOptions;
985};
986
990template <Arch arch>
991class P4RuntimeArchHandlerPSAPNA : public P4RuntimeArchHandlerCommon<arch> {
992 public:
993 P4RuntimeArchHandlerPSAPNA(ReferenceMap *refMap, TypeMap *typeMap,
994 const IR::ToplevelBlock *evaluatedProgram)
995 : P4RuntimeArchHandlerCommon<arch>(refMap, typeMap, evaluatedProgram) {}
996
998 const IR::ExternBlock *externBlock) override {
1000
1001 auto decl = externBlock->node->to<IR::IDeclaration>();
1002 if (decl == nullptr) return;
1003 if (externBlock->type->name == "Digest") {
1004 symbols->add(SymbolType::P4RT_DIGEST(), decl);
1005 }
1006 }
1007
1008 void addTableProperties(const P4RuntimeSymbolTableIface &symbols, p4configv1::P4Info *p4info,
1009 p4configv1::Table *table, const IR::TableBlock *tableBlock) override {
1010 P4RuntimeArchHandlerCommon<arch>::addTableProperties(symbols, p4info, table, tableBlock);
1011
1012 auto tableDeclaration = tableBlock->container;
1013 bool supportsTimeout = getSupportsTimeout(tableDeclaration);
1014 if (supportsTimeout) {
1015 table->set_idle_timeout_behavior(p4configv1::Table::NOTIFY_CONTROL);
1016 } else {
1017 table->set_idle_timeout_behavior(p4configv1::Table::NO_TIMEOUT);
1018 }
1019 }
1020
1021 void addExternInstance(const P4RuntimeSymbolTableIface &symbols, p4configv1::P4Info *p4info,
1022 const IR::ExternBlock *externBlock) override {
1023 P4RuntimeArchHandlerCommon<arch>::addExternInstance(symbols, p4info, externBlock);
1024
1025 auto decl = externBlock->node->to<IR::Declaration_Instance>();
1026 if (decl == nullptr) return;
1027 auto p4RtTypeInfo = p4info->mutable_type_info();
1028 if (externBlock->type->name == "Digest") {
1029 auto digest = getDigest(decl, p4RtTypeInfo);
1030 if (digest) this->addDigest(symbols, p4info, *digest);
1031 }
1032 }
1033
1035 std::optional<Digest> getDigest(const IR::Declaration_Instance *decl,
1036 p4configv1::P4TypeInfo *p4RtTypeInfo) {
1037 BUG_CHECK(decl->type->is<IR::Type_Specialized>(), "%1%: expected Type_Specialized",
1038 decl->type);
1039 auto type = decl->type->to<IR::Type_Specialized>();
1040 BUG_CHECK(type->arguments->size() == 1, "%1%: expected one type argument", decl);
1041 auto typeArg = type->arguments->at(0);
1042 auto typeSpec =
1043 TypeSpecConverter::convert(this->refMap, this->typeMap, typeArg, p4RtTypeInfo);
1044 BUG_CHECK(typeSpec != nullptr,
1045 "P4 type %1% could not be converted to P4Info P4DataTypeSpec");
1046
1047 return Digest{decl->controlPlaneName(), typeSpec, decl->to<IR::IAnnotated>()};
1048 }
1049
1052 static bool getSupportsTimeout(const IR::P4Table *table) {
1053 auto timeout = table->properties->getProperty("psa_idle_timeout");
1054
1055 if (timeout == nullptr) return false;
1056
1057 if (auto exprValue = timeout->value->to<IR::ExpressionValue>()) {
1058 if (auto expr = exprValue->expression) {
1059 if (auto member = expr->to<IR::Member>()) {
1060 if (member->member == "NOTIFY_CONTROL") {
1061 return true;
1062 } else if (member->member == "NO_TIMEOUT") {
1063 return false;
1064 }
1065 } else if (expr->is<IR::PathExpression>()) {
1066 ::P4::error(ErrorType::ERR_UNEXPECTED,
1067 "Unresolved value %1% for psa_idle_timeout "
1068 "property on table %2%. Must be a constant and one of "
1069 "{ NOTIFY_CONTROL, NO_TIMEOUT }",
1070 timeout, table);
1071 return false;
1072 }
1073 }
1074 }
1075
1076 ::P4::error(ErrorType::ERR_UNEXPECTED,
1077 "Unexpected value %1% for psa_idle_timeout "
1078 "property on table %2%. Supported values are "
1079 "{ NOTIFY_CONTROL, NO_TIMEOUT }",
1080 timeout, table);
1081 return false;
1082 }
1083};
1084
1089class P4RuntimeArchHandlerUBPF final : public P4RuntimeArchHandlerCommon<Arch::PSA> {
1090 public:
1091 P4RuntimeArchHandlerUBPF(ReferenceMap *refMap, TypeMap *typeMap,
1092 const IR::ToplevelBlock *evaluatedProgram)
1093 : P4RuntimeArchHandlerCommon<Arch::PSA>(refMap, typeMap, evaluatedProgram) {}
1094};
1095
1096class P4RuntimeArchHandlerPSA final : public P4RuntimeArchHandlerPSAPNA<Arch::PSA> {
1097 public:
1098 P4RuntimeArchHandlerPSA(ReferenceMap *refMap, TypeMap *typeMap,
1099 const IR::ToplevelBlock *evaluatedProgram)
1100 : P4RuntimeArchHandlerPSAPNA(refMap, typeMap, evaluatedProgram) {}
1101};
1102
1103class P4RuntimeArchHandlerPNA final : public P4RuntimeArchHandlerPSAPNA<Arch::PNA> {
1104 public:
1105 P4RuntimeArchHandlerPNA(ReferenceMap *refMap, TypeMap *typeMap,
1106 const IR::ToplevelBlock *evaluatedProgram)
1107 : P4RuntimeArchHandlerPSAPNA(refMap, typeMap, evaluatedProgram) {}
1108};
1109
1110} // namespace Standard
1111
1112} // namespace ControlPlaneAPI
1113 /* end group control_plane */
1115} // namespace P4
1116
1117#endif /* CONTROL_PLANE_P4RUNTIMEARCHSTANDARD_H_ */
Definition p4RuntimeArchHandler.h:130
Definition p4RuntimeArchHandler.h:100
virtual p4rt_id_t getId(P4RuntimeSymbolType type, const IR::IDeclaration *declaration) const =0
virtual cstring getAlias(cstring name) const =0
virtual void add(P4RuntimeSymbolType type, const IR::IDeclaration *declaration)=0
Add a @type symbol, extracting the name and id from @declaration.
void collectExternMethod(P4RuntimeSymbolTableIface *, const P4::ExternMethod *) override
Collects architecture-specific @externMethod instance in @symbols table.
Definition p4RuntimeArchStandard.h:582
void addExternEntries(const p4::v1::WriteRequest *, const P4RuntimeSymbolTableIface &, const IR::ExternBlock *) override
This method is called to add target specific extern entries.
Definition p4RuntimeArchStandard.h:700
static std::optional< ActionProfile > getActionProfile(const IR::P4Table *table, ReferenceMap *refMap, TypeMap *typeMap)
Definition p4RuntimeArchStandard.h:725
void collectTableProperties(P4RuntimeSymbolTableIface *symbols, const IR::TableBlock *tableBlock) override
Definition p4RuntimeArchStandard.h:532
std::set< p4rt_id_t > serializedInstances
The extern instances we've serialized so far. Used for deduplication.
Definition p4RuntimeArchStandard.h:981
void collectExternFunction(P4RuntimeSymbolTableIface *symbols, const P4::ExternFunction *externFunction) override
Definition p4RuntimeArchStandard.h:610
void collectExternInstance(P4RuntimeSymbolTableIface *symbols, const IR::ExternBlock *externBlock) override
Collects architecture-specific @externBlock instance in @symbols table.
Definition p4RuntimeArchStandard.h:584
void postAdd(const P4RuntimeSymbolTableIface &, ::p4::config::v1::P4Info *) override
Definition p4RuntimeArchStandard.h:698
void collectExtra(P4RuntimeSymbolTableIface *symbols) override
Definition p4RuntimeArchStandard.h:617
void setCounterCommon(const P4RuntimeSymbolTableIface &symbols, Kind *counter, p4rt_id_t id, const Helpers::Counterlike< ArchCounterExtern > &counterInstance)
Set common fields between Counter and DirectCounter.
Definition p4RuntimeArchStandard.h:846
static const IR::Property * getTableImplementationProperty(const IR::P4Table *table)
Definition p4RuntimeArchStandard.h:933
bool filterAnnotations(cstring) override
called when processing annotations via setPreamble
Definition p4RuntimeArchStandard.h:702
static std::optional< ActionProfile > getActionProfile(const IR::ExternBlock *instance)
Definition p4RuntimeArchStandard.h:743
google::protobuf::util::JsonPrintOptions getJsonPrintOptions() override
Control how JSON is output.
Definition p4RuntimeArchStandard.h:704
void postCollect(const P4RuntimeSymbolTableIface &symbols) override
Definition p4RuntimeArchStandard.h:622
void collectAssignmentStatement(P4RuntimeSymbolTableIface *, const IR::BaseAssignmentStatement *) override
Collects architecture-specific used in assignment statements.
Definition p4RuntimeArchStandard.h:579
void setMeterCommon(const P4RuntimeSymbolTableIface &symbols, Kind *meter, p4rt_id_t id, const Helpers::Counterlike< ArchMeterExtern > &meterInstance)
Set common fields between Meter and DirectMeter.
Definition p4RuntimeArchStandard.h:875
static bool getSupportsTimeout(const IR::P4Table *table)
Definition p4RuntimeArchStandard.h:1052
void collectExternInstance(P4RuntimeSymbolTableIface *symbols, const IR::ExternBlock *externBlock) override
Collects architecture-specific @externBlock instance in @symbols table.
Definition p4RuntimeArchStandard.h:997
std::optional< Digest > getDigest(const IR::Declaration_Instance *decl, p4configv1::P4TypeInfo *p4RtTypeInfo)
Definition p4RuntimeArchStandard.h:1035
static const ::p4::config::v1::P4DataTypeSpec * convert(const P4::ReferenceMap *refMap, P4::TypeMap *typeMap, const IR::Type *type, ::p4::config::v1::P4TypeInfo *typeInfo)
Definition typeSpecConverter.cpp:377
Definition methodInstance.h:194
Definition methodInstance.h:168
The Declaration interface, representing objects with names.
Definition declaration.h:17
Class used to encode maps from paths to declarations.
Definition referenceMap.h:67
const IR::IDeclaration * getDeclaration(const IR::Path *path, bool notNull=false) const override
Definition referenceMap.cpp:78
Definition typeMap.h:32
Definition cstring.h:85
Definition p4RuntimeArchHandler.h:100
virtual p4rt_id_t getId(P4RuntimeSymbolType type, const IR::IDeclaration *declaration) const =0
virtual cstring getAlias(cstring name) const =0
Definition tofino/bf-p4c/control-plane/bfruntime_arch_handler.h:77
void forAllEvaluatedBlocks(const IR::Block *block, Func function)
Definition p4RuntimeArchHandler.h:225
std::optional< ExternInstance > getExternInstanceFromProperty(const IR::P4Table *table, const cstring &propertyName, ReferenceMap *refMap, TypeMap *typeMap, bool *isConstructedInPlace)
Definition p4RuntimeArchHandler.cpp:30
bool isExternPropertyConstructedInPlace(const IR::P4Table *table, const cstring &propertyName)
Definition p4RuntimeArchHandler.cpp:66
std::optional< Counterlike< Kind > > getDirectCounterlike(const IR::P4Table *table, ReferenceMap *refMap, TypeMap *typeMap)
Definition p4RuntimeArchHandler.h:482
A traits class describing the properties of "counterlike" things.
Definition p4RuntimeArchHandler.h:360
Declarations specific to standard architectures (v1model & PSA).
Definition dpdk/control-plane/bfruntime_arch_handler.h:47
Arch
Definition p4RuntimeArchStandard.h:38
ActionProfileType
The types of action profiles available in v1model & PSA.
Definition p4RuntimeArchStandard.h:490
Definition p4RuntimeArchStandard.h:298
Definition p4RuntimeArchStandard.h:339
Definition p4RuntimeArchStandard.h:41
Definition p4RuntimeArchStandard.h:414
Definition p4RuntimeArchStandard.h:43
Traits for the register extern, must be specialized for v1model and PSA.
Definition p4RuntimeArchStandard.h:367
TODO(antonin): High level goals of the generator go here!!
Definition dpdk/control-plane/bfruntime_arch_handler.h:44
cstring getTypeName(const IR::Type *type, TypeMap *typeMap)
Definition typeSpecConverter.cpp:68
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
void warning(const char *format, Args &&...args)
Report a warning with the given message.
Definition lib/error.h:128
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58
Definition p4RuntimeArchHandler.h:368
const std::optional< cstring > table
If not none, the instance is a direct resource associated with @table.
Definition p4RuntimeArchHandler.h:378
const cstring name
The name of the instance.
Definition p4RuntimeArchHandler.h:370
const IR::IAnnotated * annotations
If non-null, the instance's annotations.
Definition p4RuntimeArchHandler.h:372
static std::optional< Counterlike< Kind > > from(const IR::ExternBlock *instance, const ReferenceMap *refMap, P4::TypeMap *typeMap, ::p4::config::v1::P4TypeInfo *p4RtTypeInfo)
Definition p4RuntimeArchHandler.h:385
const cstring unit
The units parameter to the instance; valid values vary depending on @Kind.
Definition p4RuntimeArchHandler.h:374
const cstring index_type_name
Definition p4RuntimeArchHandler.h:381
const int64_t size
The size parameter to the instance.
Definition p4RuntimeArchHandler.h:376
Definition p4RuntimeArchHandler.h:195
Definition p4RuntimeArchStandard.h:494
The architecture handler builder implementation for PNA.
Definition p4RuntimeArchStandard.h:255
P4RuntimeArchHandlerIface * operator()(ReferenceMap *refMap, TypeMap *typeMap, const IR::ToplevelBlock *evaluatedProgram) const override
Definition p4RuntimeArchStandard.cpp:149
The architecture handler builder implementation for PSA.
Definition p4RuntimeArchStandard.h:249
P4RuntimeArchHandlerIface * operator()(ReferenceMap *refMap, TypeMap *typeMap, const IR::ToplevelBlock *evaluatedProgram) const override
Definition p4RuntimeArchStandard.cpp:144
Definition p4RuntimeArchStandard.h:423
static std::optional< Register > from(const IR::ExternBlock *instance, const ReferenceMap *refMap, P4::TypeMap *typeMap, p4configv1::P4TypeInfo *p4RtTypeInfo)
Definition p4RuntimeArchStandard.h:436
The architecture handler builder implementation for UBPF.
Definition p4RuntimeArchStandard.h:261
P4RuntimeArchHandlerIface * operator()(ReferenceMap *refMap, TypeMap *typeMap, const IR::ToplevelBlock *evaluatedProgram) const override
Definition p4RuntimeArchStandard.cpp:154
The architecture handler builder implementation for v1model.
Definition p4RuntimeArchStandard.h:243
P4RuntimeArchHandlerIface * operator()(ReferenceMap *refMap, TypeMap *typeMap, const IR::ToplevelBlock *evaluatedProgram) const override
Definition p4RuntimeArchStandard.cpp:139
T * to() noexcept
Definition rtti.h:226