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