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