P4C
The P4 Compiler
Loading...
Searching...
No Matches
bmv2/common/backend.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef BACKENDS_BMV2_COMMON_BACKEND_H_
9#define BACKENDS_BMV2_COMMON_BACKEND_H_
10
11#include "JsonObjects.h"
12#include "controlFlowGraph.h"
13#include "expression.h"
14#include "frontends/common/model.h"
15#include "frontends/p4/coreLibrary.h"
16#include "helpers.h"
17#include "ir/annotations.h"
18#include "ir/ir.h"
19#include "lib/cstring.h"
20#include "lib/error.h"
21#include "lib/exceptions.h"
22#include "lib/gc.h"
23#include "lib/json.h"
24#include "lib/log.h"
25#include "lib/nullstream.h"
26#include "midend/actionSynthesis.h"
27#include "midend/convertEnums.h"
28#include "midend/removeComplexExpressions.h"
29#include "midend/removeLeftSlices.h"
30#include "options.h"
31#include "sharedActionSelectorCheck.h"
32
33namespace P4::BMV2 {
34
35enum gress_t { INGRESS, EGRESS };
36enum block_t {
37 PARSER,
38 PIPELINE,
39 DEPARSER,
40 V1_PARSER,
41 V1_DEPARSER,
42 V1_INGRESS,
43 V1_EGRESS,
44 V1_VERIFY,
45 V1_COMPUTE
46};
47
49
51class Backend {
52 public:
53 BMV2Options &options;
54 P4::ReferenceMap *refMap;
55 P4::TypeMap *typeMap;
56 P4::ConvertEnums::EnumMapping *enumMap;
57 P4::P4CoreLibrary &corelib;
59 const IR::ToplevelBlock *toplevel = nullptr;
60
61 public:
62 Backend(BMV2Options &options, P4::ReferenceMap *refMap, P4::TypeMap *typeMap,
63 P4::ConvertEnums::EnumMapping *enumMap)
64 : options(options),
65 refMap(refMap),
66 typeMap(typeMap),
67 enumMap(enumMap),
68 corelib(P4::P4CoreLibrary::instance()),
69 json(new BMV2::JsonObjects()) {
70#ifdef SUPPORT_P4_14
71 refMap->setIsV1(options.isv1());
72#endif
73 }
74 void serialize(std::ostream &out) const { json->toplevel->serialize(out); }
75 virtual void convert(const IR::ToplevelBlock *block) = 0;
76};
77
79// The policy is: do not synthesize actions for the controls whose names
83class SkipControls : public P4::ActionSynthesisPolicy {
85 const std::set<cstring> *skip;
86
87 public:
88 explicit SkipControls(const std::set<cstring> *skip) : skip(skip) { CHECK_NULL(skip); }
89 bool convert(const Visitor::Context *, const IR::P4Control *control) override {
90 if (skip->find(control->name) != skip->end()) return false;
91 return true;
92 }
93};
94
100class ProcessControls : public P4::RemoveComplexExpressionsPolicy {
101 const std::set<cstring> *process;
102
103 public:
104 explicit ProcessControls(const std::set<cstring> *process) : process(process) {
105 CHECK_NULL(process);
106 }
107 bool convert(const IR::P4Control *control) const {
108 if (process->find(control->name) != process->end()) return true;
109 return false;
110 }
111};
112
117class RenameUserMetadata : public Transform {
118 P4::ReferenceMap *refMap;
119 const IR::Type_Struct *userMetaType;
122 cstring namePrefix;
123 bool renamed = false;
124
125 public:
126 RenameUserMetadata(P4::ReferenceMap *refMap, const IR::Type_Struct *userMetaType,
127 cstring namePrefix)
128 : refMap(refMap), userMetaType(userMetaType), namePrefix(namePrefix) {
129 setName("RenameUserMetadata");
130 CHECK_NULL(refMap);
131 visitDagOnce = false;
132 }
133
134 const IR::Node *postorder(IR::Type_Struct *type) override {
135 // Clone the user metadata type
136 auto orig = getOriginal<IR::Type_Struct>();
137 if (userMetaType->name != orig->name) return type;
138
139 auto vec = new IR::IndexedVector<IR::Node>();
140 LOG2("Creating clone of " << orig);
141 renamed = true;
142 auto clone = type->clone();
143 clone->name = namePrefix;
144 vec->push_back(clone);
145
146 // Rename all fields
148 for (auto f : type->fields) {
149 auto anno = f->getAnnotation(IR::Annotation::nameAnnotation);
150 cstring suffix = cstring::empty;
151 if (anno != nullptr) suffix = anno->getName();
152 if (suffix.startsWith(".")) {
153 // We can't change the name of this field.
154 // Hopefully the user knows what they are doing.
155 fields.push_back(f->clone());
156 continue;
157 }
158
159 if (!suffix.isNullOrEmpty())
160 suffix = "."_cs + suffix;
161 else
162 suffix = "."_cs + f->name;
163 cstring newName = namePrefix + suffix;
164 LOG2("Renaming " << f << " to " << newName);
165 auto field = new IR::StructField(
166 f->srcInfo, f->name, IR::Annotations::setNameAnnotation(f->annotations, newName),
167 f->type);
168 fields.push_back(field);
169 }
170
171 auto annotated =
172 new IR::Type_Struct(type->srcInfo, type->name, type->annotations, std::move(fields));
173 vec->push_back(annotated);
174 return vec;
175 }
176
177 const IR::Node *preorder(IR::Type_Name *type) override {
178 // Find any reference to the user metadata type that is used and replace them
179 auto decl = refMap->getDeclaration(type->path);
180 if (decl == userMetaType)
181 type->path = new IR::Path(type->path->srcInfo, IR::ID(type->path->srcInfo, namePrefix));
182 LOG2("Replacing reference with " << type);
183 return type;
184 }
185
186 void end_apply(const IR::Node *) override {
187 BUG_CHECK(renamed, "Could not identify user metadata type declaration %1%", userMetaType);
188 }
189};
190
191} // namespace P4::BMV2
192
193#endif /* BACKENDS_BMV2_COMMON_BACKEND_H_ */
Definition actionSynthesis.h:21
Definition backends/bmv2/common/options.h:18
Definition expression.h:42
Definition JsonObjects.h:17
bool convert(const IR::P4Control *control) const
Definition bmv2/common/backend.h:107
bool convert(const Visitor::Context *, const IR::P4Control *control) override
Definition bmv2/common/backend.h:89
Definition indexed_vector.h:31
Definition node.h:44
Definition coreLibrary.h:94
Class used to encode maps from paths to declarations.
Definition referenceMap.h:58
Definition removeComplexExpressions.h:21
Definition typeMap.h:32
Definition cstring.h:76
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition action.cpp:9
Definition bson.cpp:69
Definition id.h:19