17#ifndef CONTROL_PLANE_P4RUNTIMEARCHHANDLER_H_
18#define CONTROL_PLANE_P4RUNTIMEARCHHANDLER_H_
20#pragma GCC diagnostic push
21#pragma GCC diagnostic ignored "-Wunused-parameter"
22#pragma GCC diagnostic ignored "-Wpedantic"
23#include <google/protobuf/util/json_util.h>
24#pragma GCC diagnostic pop
29#pragma GCC diagnostic push
30#pragma GCC diagnostic ignored "-Wunused-parameter"
31#pragma GCC diagnostic ignored "-Wpedantic"
32#include "p4/config/v1/p4info.pb.h"
33#include "p4/v1/p4runtime.pb.h"
34#pragma GCC diagnostic pop
36#include "frontends/common/resolveReferences/referenceMap.h"
37#include "frontends/p4/externInstance.h"
38#include "frontends/p4/methodInstance.h"
39#include "frontends/p4/typeMap.h"
41#include "lib/cstring.h"
42#include "lib/ordered_set.h"
43#include "typeSpecConverter.h"
47using namespace literals;
52namespace ControlPlaneAPI {
54using p4rt_id_t = uint32_t;
70 explicit operator p4rt_id_t()
const {
return id; }
75 static P4RuntimeSymbolType P4RT_TABLE() {
76 return P4RuntimeSymbolType(::p4::config::v1::P4Ids::TABLE);
78 static P4RuntimeSymbolType P4RT_VALUE_SET() {
79 return P4RuntimeSymbolType(::p4::config::v1::P4Ids::VALUE_SET);
81 static P4RuntimeSymbolType P4RT_CONTROLLER_HEADER() {
82 return P4RuntimeSymbolType(::p4::config::v1::P4Ids::CONTROLLER_HEADER);
85 static P4RuntimeSymbolType P4RT_OTHER_EXTERNS_START() {
86 return P4RuntimeSymbolType(::p4::config::v1::P4Ids::OTHER_EXTERNS_START);
89 bool operator==(
const P4RuntimeSymbolType &other)
const {
return id == other.id; }
91 bool operator!=(
const P4RuntimeSymbolType &other)
const {
return !(*
this == other); }
93 bool operator<(
const P4RuntimeSymbolType &other)
const {
return id < other.id; }
96 static P4RuntimeSymbolType make(p4rt_id_t
id) {
return P4RuntimeSymbolType(
id); }
101 explicit constexpr P4RuntimeSymbolType(p4rt_id_t
id) noexcept : id(
id) {}
116 std::optional<p4rt_id_t>
id = std::nullopt) = 0;
144 auto decl = block->getContainer();
145 return decl ? decl->controlPlaneName() : cstring::empty;
150 const IR::TableBlock *tableBlock) = 0;
153 const IR::ExternBlock *externBlock) = 0;
156 const IR::AssignmentStatement *assign) = 0;
173 ::p4::config::v1::P4Info *p4info,
174 ::p4::config::v1::Table *table,
175 const IR::TableBlock *tableBlock) = 0;
179 ::p4::config::v1::P4Info *p4info,
180 const IR::ExternBlock *externBlock) = 0;
184 ::p4::config::v1::P4Info *p4info,
189 ::p4::config::v1::P4Info *p4info) = 0;
193 const IR::ExternBlock *externBlock) = 0;
213 const IR::ToplevelBlock *evaluatedProgram)
const = 0;
225 bool *isConstructedInPlace =
nullptr);
233template <
typename Func>
235 std::set<const IR::Block *> visited;
238 while (!frontier.empty()) {
240 auto evaluatedBlock = *frontier.begin();
241 frontier.erase(frontier.begin());
242 visited.insert(evaluatedBlock);
244 function(evaluatedBlock);
247 for (
auto evaluatedChild : evaluatedBlock->constantValue) {
249 if (!evaluatedChild.second)
continue;
250 if (!evaluatedChild.second->is<IR::Block>())
continue;
251 auto evaluatedChildBlock = evaluatedChild.second->to<IR::Block>();
252 if (visited.find(evaluatedChildBlock) != visited.end())
continue;
253 frontier.insert(evaluatedChildBlock);
262void serializeOneStructuredAnnotation(
const IR::Annotation *annotation,
263 ::p4::config::v1::StructuredAnnotation *structuredAnnotation);
270template <
typename Message,
typename UnaryPredicate>
271void addAnnotations(Message *message,
const IR::IAnnotated *annotated, UnaryPredicate p) {
275 if (annotated ==
nullptr)
return;
277 for (
const IR::Annotation *annotation : annotated->getAnnotations()) {
279 if (annotation->annotationKind() != IR::Annotation::Kind::Unstructured &&
280 annotation->annotationKind() != IR::Annotation::Kind::Unparsed) {
281 serializeOneStructuredAnnotation(annotation, message->add_structured_annotations());
286 if (annotation->name == IR::Annotation::nameAnnotation)
continue;
287 if (annotation->name ==
"id")
continue;
291 if (annotation->name ==
"brief" || annotation->name ==
"description")
continue;
293 if (p(annotation->name))
continue;
300template <
typename Message>
301void addAnnotations(Message *message,
const IR::IAnnotated *annotated) {
302 addAnnotations(message, annotated, [](
cstring) {
return false; });
307template <
typename Message>
312 if (annotated ==
nullptr)
return;
314 ::p4::config::v1::Documentation doc;
320 for (
const IR::Annotation *annotation : annotated->getAnnotations()) {
321 if (annotation->name ==
"brief") {
322 auto brief = annotation->getExpr(0)->to<IR::StringLiteral>();
325 doc.set_brief(brief->value);
329 if (annotation->name ==
"description") {
330 auto description = annotation->getExpr(0)->to<IR::StringLiteral>();
332 CHECK_NULL(description);
333 doc.set_description(description->value);
339 if (hasDoc) message->mutable_doc()->CopyFrom(doc);
345template <
typename UnaryPredicate>
346void setPreamble(::p4::config::v1::Preamble *preamble, p4rt_id_t
id,
cstring name,
cstring alias,
347 const IR::IAnnotated *annotated, UnaryPredicate p) {
348 CHECK_NULL(preamble);
349 preamble->set_id(
id);
350 preamble->set_name(name);
351 preamble->set_alias(alias);
352 addAnnotations(preamble, annotated, p);
358inline void setPreamble(::p4::config::v1::Preamble *preamble, p4rt_id_t
id,
cstring name,
359 cstring alias,
const IR::IAnnotated *annotated) {
360 setPreamble(preamble,
id, name, alias, annotated, [](
cstring) {
return false; });
368template <
typename Kind>
376template <
typename Kind>
394 static std::optional<Counterlike<Kind>>
from(
const IR::ExternBlock *instance,
396 ::p4::config::v1::P4TypeInfo *p4RtTypeInfo) {
397 CHECK_NULL(instance);
398 auto declaration = instance->node->to<IR::Declaration_Instance>();
403 auto unit = instance->getParameterValue(
"type"_cs);
404 if (!
unit->is<IR::Declaration_ID>()) {
406 "%1% '%2%' has a unit type which is not an enum constant: %3%",
413 if (
size->template is<IR::Constant>()) {
414 val =
size->template to<IR::Constant>()->value;
415 }
else if (
size->template is<IR::SerEnumMember>()) {
416 auto sem =
size->template to<IR::SerEnumMember>();
417 val = sem->value->template to<IR::Constant>()->value;
419 ::P4::error(ErrorType::ERR_INVALID,
"%1% '%2%' has a non-constant size: %3%",
427 if (indexTypeParamIdx != std::nullopt) {
429 BUG_CHECK(declaration->type->is<IR::Type_Specialized>(),
430 "%1%: expected Type_Specialized", declaration->type);
431 auto type = declaration->type->to<IR::Type_Specialized>();
432 BUG_CHECK(type->arguments->size() > *indexTypeParamIdx,
433 "%1%: expected at least %2% type arguments", instance,
434 *indexTypeParamIdx + 1);
435 auto typeArg = type->arguments->at(*indexTypeParamIdx);
443 declaration->to<IR::IAnnotated>(),
444 unit->to<IR::Declaration_ID>()->name,
454 const IR::P4Table *
table) {
456 BUG_CHECK(instance.name != std::nullopt,
"Caller should've ensured we have a name");
459 ::P4::error(ErrorType::ERR_EXPECTED,
"Expected a direct %1%: %2%",
464 auto unitArgument = instance.substitution.lookupByName(
"type"_cs)->expression;
465 if (unitArgument ==
nullptr) {
467 "Direct %1% instance %2% should take a constructor argument",
471 if (!unitArgument->is<IR::Member>()) {
473 "Direct %1% instance %2% has an unexpected constructor argument",
478 auto unit = unitArgument->to<IR::Member>()->member.name;
480 instance.annotations,
483 table->controlPlaneName(),
490template <
typename Kind>
495 if (!instance)
return std::nullopt;
Definition p4RuntimeArchHandler.h:139
virtual void collectTableProperties(P4RuntimeSymbolTableIface *symbols, const IR::TableBlock *tableBlock)=0
virtual void addExternInstance(const P4RuntimeSymbolTableIface &symbols, ::p4::config::v1::P4Info *p4info, const IR::ExternBlock *externBlock)=0
virtual void postAdd(const P4RuntimeSymbolTableIface &symbols, ::p4::config::v1::P4Info *p4info)=0
virtual void addTableProperties(const P4RuntimeSymbolTableIface &symbols, ::p4::config::v1::P4Info *p4info, ::p4::config::v1::Table *table, const IR::TableBlock *tableBlock)=0
virtual cstring getControlPlaneName(const IR::Block *block)
Get control plane name for @block.
Definition p4RuntimeArchHandler.h:143
virtual void collectExternFunction(P4RuntimeSymbolTableIface *symbols, const P4::ExternFunction *externFunction)=0
virtual void addExternFunction(const P4RuntimeSymbolTableIface &symbols, ::p4::config::v1::P4Info *p4info, const P4::ExternFunction *externFunction)=0
virtual void postCollect(const P4RuntimeSymbolTableIface &symbols)=0
virtual google::protobuf::util::JsonPrintOptions getJsonPrintOptions()=0
Control how JSON is output.
virtual void collectExternInstance(P4RuntimeSymbolTableIface *symbols, const IR::ExternBlock *externBlock)=0
Collects architecture-specific @externBlock instance in @symbols table.
virtual bool filterAnnotations(cstring anno)=0
called when processing annotations via setPreamble
virtual void collectExternMethod(P4RuntimeSymbolTableIface *symbols, const P4::ExternMethod *externMethod)=0
Collects architecture-specific @externMethod instance in @symbols table.
virtual void collectAssignmentStatement(P4RuntimeSymbolTableIface *symbols, const IR::AssignmentStatement *assign)=0
Collects architecture-specific used in assignment statements.
virtual void addExternEntries(const p4::v1::WriteRequest *entries, const P4RuntimeSymbolTableIface &symbols, const IR::ExternBlock *externBlock)=0
This method is called to add target specific extern entries.
virtual void collectExtra(P4RuntimeSymbolTableIface *symbols)=0
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
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:390
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
Definition ordered_set.h:32
Definition tofino/bf-p4c/control-plane/bfruntime_arch_handler.h:78
void forAllEvaluatedBlocks(const IR::Block *block, Func function)
Definition p4RuntimeArchHandler.h:234
std::string serializeOneAnnotation(const IR::Annotation *annotation)
Serialize an unstructured @annotation to a string.
Definition p4RuntimeArchHandler.cpp:119
std::optional< ExternInstance > getExternInstanceFromProperty(const IR::P4Table *table, const cstring &propertyName, ReferenceMap *refMap, TypeMap *typeMap, bool *isConstructedInPlace)
Definition p4RuntimeArchHandler.cpp:41
bool isExternPropertyConstructedInPlace(const IR::P4Table *table, const cstring &propertyName)
Definition p4RuntimeArchHandler.cpp:77
int64_t getTableSize(const IR::P4Table *table)
Definition p4RuntimeArchHandler.cpp:91
void addDocumentation(Message *message, const IR::IAnnotated *annotated)
' and '@description' annotations if present.
Definition p4RuntimeArchHandler.h:308
std::optional< Counterlike< Kind > > getDirectCounterlike(const IR::P4Table *table, ReferenceMap *refMap, TypeMap *typeMap)
Definition p4RuntimeArchHandler.h:491
A traits class describing the properties of "counterlike" things.
Definition p4RuntimeArchHandler.h:369
cstring getTypeName(const IR::Type *type, TypeMap *typeMap)
Definition typeSpecConverter.cpp:81
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:51
Definition p4RuntimeArchHandler.h:377
const std::optional< cstring > table
If not none, the instance is a direct resource associated with @table.
Definition p4RuntimeArchHandler.h:387
const cstring name
The name of the instance.
Definition p4RuntimeArchHandler.h:379
const IR::IAnnotated * annotations
If non-null, the instance's annotations.
Definition p4RuntimeArchHandler.h:381
static std::optional< Counterlike< Kind > > from(const IR::ExternBlock *instance, const ReferenceMap *refMap, P4::TypeMap *typeMap, ::p4::config::v1::P4TypeInfo *p4RtTypeInfo)
Definition p4RuntimeArchHandler.h:394
const cstring unit
The units parameter to the instance; valid values vary depending on @Kind.
Definition p4RuntimeArchHandler.h:383
const cstring index_type_name
Definition p4RuntimeArchHandler.h:390
static std::optional< Counterlike< Kind > > fromDirect(const ExternInstance &instance, const IR::P4Table *table)
Definition p4RuntimeArchHandler.h:453
const int64_t size
The size parameter to the instance.
Definition p4RuntimeArchHandler.h:385
Definition p4RuntimeArchHandler.h:204
virtual P4RuntimeArchHandlerIface * operator()(ReferenceMap *refMap, TypeMap *typeMap, const IR::ToplevelBlock *evaluatedProgram) const =0
Definition externInstance.h:51