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 refMap->setIsV1(options.isv1());
71 }
72 void serialize(std::ostream &out) const { json->toplevel->serialize(out); }
73 virtual void convert(const IR::ToplevelBlock *block) = 0;
74};
75
77// The policy is: do not synthesize actions for the controls whose names
81class SkipControls : public P4::ActionSynthesisPolicy {
83 const std::set<cstring> *skip;
84
85 public:
86 explicit SkipControls(const std::set<cstring> *skip) : skip(skip) { CHECK_NULL(skip); }
87 bool convert(const Visitor::Context *, const IR::P4Control *control) override {
88 if (skip->find(control->name) != skip->end()) return false;
89 return true;
90 }
91};
92
98class ProcessControls : public P4::RemoveComplexExpressionsPolicy {
99 const std::set<cstring> *process;
100
101 public:
102 explicit ProcessControls(const std::set<cstring> *process) : process(process) {
103 CHECK_NULL(process);
104 }
105 bool convert(const IR::P4Control *control) const {
106 if (process->find(control->name) != process->end()) return true;
107 return false;
108 }
109};
110
115class RenameUserMetadata : public Transform {
116 P4::ReferenceMap *refMap;
117 const IR::Type_Struct *userMetaType;
120 cstring namePrefix;
121 bool renamed = false;
122
123 public:
124 RenameUserMetadata(P4::ReferenceMap *refMap, const IR::Type_Struct *userMetaType,
125 cstring namePrefix)
126 : refMap(refMap), userMetaType(userMetaType), namePrefix(namePrefix) {
127 setName("RenameUserMetadata");
128 CHECK_NULL(refMap);
129 visitDagOnce = false;
130 }
131
132 const IR::Node *postorder(IR::Type_Struct *type) override {
133 // Clone the user metadata type
134 auto orig = getOriginal<IR::Type_Struct>();
135 if (userMetaType->name != orig->name) return type;
136
137 auto vec = new IR::IndexedVector<IR::Node>();
138 LOG2("Creating clone of " << orig);
139 renamed = true;
140 auto clone = type->clone();
141 clone->name = namePrefix;
142 vec->push_back(clone);
143
144 // Rename all fields
146 for (auto f : type->fields) {
147 auto anno = f->getAnnotation(IR::Annotation::nameAnnotation);
148 cstring suffix = cstring::empty;
149 if (anno != nullptr) suffix = anno->getName();
150 if (suffix.startsWith(".")) {
151 // We can't change the name of this field.
152 // Hopefully the user knows what they are doing.
153 fields.push_back(f->clone());
154 continue;
155 }
156
157 if (!suffix.isNullOrEmpty())
158 suffix = "."_cs + suffix;
159 else
160 suffix = "."_cs + f->name;
161 cstring newName = namePrefix + suffix;
162 LOG2("Renaming " << f << " to " << newName);
163 auto field = new IR::StructField(
164 f->srcInfo, f->name, IR::Annotations::setNameAnnotation(f->annotations, newName),
165 f->type);
166 fields.push_back(field);
167 }
168
169 auto annotated =
170 new IR::Type_Struct(type->srcInfo, type->name, type->annotations, std::move(fields));
171 vec->push_back(annotated);
172 return vec;
173 }
174
175 const IR::Node *preorder(IR::Type_Name *type) override {
176 // Find any reference to the user metadata type that is used and replace them
177 auto decl = refMap->getDeclaration(type->path);
178 if (decl == userMetaType)
179 type->path = new IR::Path(type->path->srcInfo, IR::ID(type->path->srcInfo, namePrefix));
180 LOG2("Replacing reference with " << type);
181 return type;
182 }
183
184 void end_apply(const IR::Node *) override {
185 BUG_CHECK(renamed, "Could not identify user metadata type declaration %1%", userMetaType);
186 }
187};
188
189} // namespace P4::BMV2
190
191#endif /* BACKENDS_BMV2_COMMON_BACKEND_H_ */
Definition actionSynthesis.h:30
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:105
bool convert(const Visitor::Context *, const IR::P4Control *control) override
Definition bmv2/common/backend.h:87
Definition indexed_vector.h:31
Definition node.h:53
Definition coreLibrary.h:103
Class used to encode maps from paths to declarations.
Definition referenceMap.h:67
Definition removeComplexExpressions.h:21
Definition typeMap.h:32
Definition cstring.h:85
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition action.cpp:9
Definition bson.cpp:69
Definition id.h:28