P4C
The P4 Compiler
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
frontends/p4/fromv1.0/programStructure.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 FRONTENDS_P4_FROMV1_0_PROGRAMSTRUCTURE_H_
18#define FRONTENDS_P4_FROMV1_0_PROGRAMSTRUCTURE_H_
19
20#include <set>
21#include <vector>
22
23#include "frontends/p4/callGraph.h"
24#include "frontends/p4/coreLibrary.h"
25#include "ir/ir.h"
26#include "lib/cstring.h"
27#include "lib/map.h"
28#include "v1model.h"
29
30namespace P4V1 {
31
33 public:
34 const IR::Expression *header = nullptr;
35 const IR::Expression *userMetadata = nullptr;
36 const IR::Expression *standardMetadata = nullptr;
37 virtual void clear() {
38 header = nullptr;
39 userMetadata = nullptr;
40 standardMetadata = nullptr;
41 }
42};
43
46 // In P4-14 one can have multiple objects with different types with the same name
47 // In P4-16 this is not possible, so we may need to rename some objects.
48 // We will preserve the original name using an @name("") annotation.
49 template <typename T>
50 class NamedObjectInfo {
51 // If allNames is nullptr we don't check for duplicate names.
52 // Key is a name, value represents how many times this name was used as a base
53 // for newly generated unique names.
54 std::unordered_map<cstring, int> *allNames;
55 std::map<cstring, T> nameToObject;
56 std::map<T, cstring> objectToNewName;
57
58 // Iterate in order of name, but return pair<T, newname>
59 class iterator {
60 friend class NamedObjectInfo;
61
62 private:
63 typename std::map<cstring, T>::iterator it;
64 typename std::map<T, cstring> &objToName;
65 iterator(typename std::map<cstring, T>::iterator it,
66 typename std::map<T, cstring> &objToName)
67 : it(it), objToName(objToName) {}
68
69 public:
70 const iterator &operator++() {
71 ++it;
72 return *this;
73 }
74 bool operator!=(const iterator &other) const { return it != other.it; }
75 std::pair<T, cstring> operator*() const {
76 return std::pair<T, cstring>(it->second, objToName[it->second]);
77 }
78 };
79
80 public:
81 explicit NamedObjectInfo(std::unordered_map<cstring, int> *allNames) : allNames(allNames) {}
82 void emplace(T obj) {
83 if (objectToNewName.find(obj) != objectToNewName.end()) {
84 // Already done
85 LOG3(" already emplaced obj " << obj);
86 return;
87 }
88
89 nameToObject.emplace(obj->name, obj);
90 cstring newName;
91
92 if (allNames == nullptr || (allNames->find(obj->name) == allNames->end())) {
93 newName = obj->name;
94 } else {
95 newName = cstring::make_unique(*allNames, obj->name, allNames->at(obj->name), '_');
96 }
97 if (allNames != nullptr) allNames->insert({newName, 0});
98 LOG3("Discovered " << obj << " named " << newName);
99 objectToNewName.emplace(obj, newName);
100 }
102 T get(cstring name) const { return ::get(nameToObject, name); }
104 cstring get(T object) const { return ::get(objectToNewName, object, object->name.name); }
106 cstring newname(cstring name) const { return get(get(name)); }
107 bool contains(cstring name) const { return nameToObject.find(name) != nameToObject.end(); }
108 iterator begin() { return iterator(nameToObject.begin(), objectToNewName); }
109 iterator end() { return iterator(nameToObject.end(), objectToNewName); }
110 void erase(cstring name) {
111 allNames->erase(name);
112 auto obj = get(name);
113 objectToNewName.erase(obj);
114 nameToObject.erase(name);
115 }
116 };
117
118 std::set<cstring> included_files;
119
120 public:
122
123 P4V1::V1Model &v1model;
124 P4::P4CoreLibrary &p4lib;
125
126 std::unordered_map<cstring, int> allNames;
127 NamedObjectInfo<const IR::Type_StructLike *> types;
128 NamedObjectInfo<const IR::HeaderOrMetadata *> metadata;
129 NamedObjectInfo<const IR::Header *> headers;
130 NamedObjectInfo<const IR::HeaderStack *> stacks;
131 NamedObjectInfo<const IR::V1Control *> controls;
132 NamedObjectInfo<const IR::V1Parser *> parserStates;
133 NamedObjectInfo<const IR::V1Table *> tables;
134 NamedObjectInfo<const IR::ActionFunction *> actions;
135 NamedObjectInfo<const IR::Counter *> counters;
136 NamedObjectInfo<const IR::Register *> registers;
137 NamedObjectInfo<const IR::Meter *> meters;
138 NamedObjectInfo<const IR::ActionProfile *> action_profiles;
139 NamedObjectInfo<const IR::FieldList *> field_lists;
140 NamedObjectInfo<const IR::FieldListCalculation *> field_list_calculations;
141 NamedObjectInfo<const IR::ActionSelector *> action_selectors;
142 NamedObjectInfo<const IR::Type_Extern *> extern_types;
143 std::map<const IR::Type_Extern *, const IR::Type_Extern *> extern_remap;
144 NamedObjectInfo<const IR::Declaration_Instance *> externs;
145 NamedObjectInfo<const IR::ParserValueSet *> value_sets;
146 std::set<cstring> value_sets_implemented;
147 std::vector<const IR::CalculatedField *> calculated_fields;
148 std::map<const IR::Node *, const IR::Declaration_Instance *> globalInstances;
149 P4::CallGraph<cstring> calledActions;
150 P4::CallGraph<cstring> calledControls;
151 P4::CallGraph<cstring> calledCounters;
152 P4::CallGraph<cstring> calledMeters;
153 P4::CallGraph<cstring> calledRegisters;
154 P4::CallGraph<cstring> calledExterns;
156 std::map<cstring, IR::Vector<IR::Expression>> extracts; // for each parser
157 std::map<cstring, cstring> directCounters;
159 std::map<cstring, const IR::Meter *> directMeters;
160 std::map<const IR::Meter *, const IR::Declaration_Instance *> meterMap;
161 std::map<cstring, const IR::Declaration_Instance *> counterMap;
164
165 std::map<const IR::V1Table *, const IR::V1Control *> tableMapping;
166 std::map<const IR::V1Table *, const IR::Apply *> tableInvocation;
171 std::map<cstring, const IR::Type *> finalHeaderType;
174 std::map<cstring, cstring> registerLayoutType;
175
179 std::map<const IR::MethodCallExpression *, const IR::Type_Header *> extractsSynthesized;
180
181 std::map<cstring, const IR::ParserState *> parserEntryPoints;
184
185 // P4-14 struct/header type can be converted to three types
186 // of struct/header in P4-16.
187 // 1) as part of the 'hdr' struct
188 // 2) as part of the 'meta' struct
189 // 3) as the parameters of a parser/control block
190 // In case 1 and 2, the converter needs to fix the path
191 // by prepending 'hdr.' or 'meta.' to the ConcreteHeaderRef.
192 // In case 3. the converter only needs to convert headerRef to PathExpression
193 std::set<cstring> headerTypes;
194 std::set<cstring> metadataTypes;
195 std::set<cstring> parameterTypes;
196 std::set<cstring> metadataInstances;
197 std::set<cstring> headerInstances;
198
200 std::vector<const IR::Declaration *> localInstances;
201
202 ConversionContext *conversionContext = nullptr;
203
204 IR::Vector<IR::Type> *emptyTypeArguments = nullptr;
205 const IR::Parameter *parserPacketIn = nullptr;
206 const IR::Parameter *parserHeadersOut = nullptr;
207
208 // output is constructed here
209 IR::Vector<IR::Node> *declarations;
210
211 protected:
212 virtual const IR::Statement *convertPrimitive(const IR::Primitive *primitive);
213 virtual void checkHeaderType(const IR::Type_StructLike *hrd, bool toStruct);
214
232 static const IR::Annotations *addNameAnnotation(cstring name,
233 const IR::Annotations *annos = nullptr);
234
240 static const IR::Annotations *addGlobalNameAnnotation(cstring name,
241 const IR::Annotations *annos = nullptr);
242
243 virtual const IR::ParserState *convertParser(const IR::V1Parser *,
245 virtual const IR::Statement *convertParserStatement(const IR::Expression *expr);
246 virtual const IR::P4Control *convertControl(const IR::V1Control *control, cstring newName);
247 virtual const IR::Declaration_Instance *convertDirectMeter(const IR::Meter *m, cstring newName);
248 virtual const IR::Declaration_Instance *convertDirectCounter(const IR::Counter *c,
249 cstring newName);
250 virtual const IR::Declaration_Instance *convert(const IR::CounterOrMeter *cm, cstring newName);
251 virtual const IR::Declaration_Instance *convertActionProfile(const IR::ActionProfile *,
252 cstring newName);
253 virtual const IR::P4Table *convertTable(const IR::V1Table *table, cstring newName,
255 std::map<cstring, cstring> &);
256 virtual const IR::P4Action *convertAction(const IR::ActionFunction *action, cstring newName,
257 const IR::Meter *meterToAccess,
258 cstring counterToAccess);
259 virtual const IR::Statement *convertMeterCall(const IR::Meter *meterToAccess);
260 virtual const IR::Statement *convertCounterCall(cstring counterToAccess);
261 virtual const IR::Type_Control *controlType(IR::ID name);
262 const IR::PathExpression *getState(IR::ID dest);
263 virtual const IR::Expression *counterType(const IR::CounterOrMeter *cm);
264 virtual void createChecksumVerifications();
265 virtual void createChecksumUpdates();
266 virtual void createStructures();
267 virtual cstring createType(const IR::Type_StructLike *type, bool header,
268 std::unordered_set<const IR::Type *> *converted);
269 virtual void createParser();
270 virtual void createControls();
271 void createDeparserInternal(IR::ID deparserId, IR::Parameter *packetOut, IR::Parameter *headers,
272 std::vector<IR::Parameter *>,
274 std::function<IR::BlockStatement *(IR::BlockStatement *)>);
275 virtual void createDeparser();
276 virtual void createMain();
277
278 public:
279 void include(cstring filename, cstring ppoptions = cstring());
282 void populateOutputNames();
283 const IR::AssignmentStatement *assign(Util::SourceInfo srcInfo, const IR::Expression *left,
284 const IR::Expression *right, const IR::Type *type);
285 virtual const IR::Expression *convertFieldList(const IR::Expression *expression);
286 virtual const IR::Expression *convertHashAlgorithm(Util::SourceInfo srcInfo, IR::ID algorithm);
287 virtual const IR::Expression *convertHashAlgorithms(const IR::NameList *algorithm);
288 virtual const IR::Declaration_Instance *convert(const IR::Register *reg, cstring newName,
289 const IR::Type *regElementType = nullptr);
290 virtual const IR::Type_Struct *createFieldListType(const IR::Expression *expression);
291 virtual const IR::FieldListCalculation *getFieldListCalculation(const IR::Expression *);
292 virtual const IR::FieldList *getFieldLists(const IR::FieldListCalculation *flc);
293 virtual const IR::Expression *paramReference(const IR::Parameter *param);
294 const IR::Statement *sliceAssign(const IR::Primitive *prim, const IR::Expression *left,
295 const IR::Expression *right, const IR::Expression *mask);
296 void tablesReferred(const IR::V1Control *control, std::vector<const IR::V1Table *> &out);
297 bool isHeader(const IR::ConcreteHeaderRef *nhr) const;
298 cstring makeUniqueName(cstring base);
299 bool isFieldInList(cstring type, cstring field, const IR::FieldList *fl) const;
302 virtual const IR::Vector<IR::Expression> *listIndexes(cstring type, cstring field) const;
305 const IR::Expression *listIndex(const IR::Expression *fl) const;
306
307 const IR::Type *explodeType(const std::vector<const IR::Type::Bits *> &fieldTypes);
308 const IR::Expression *explodeLabel(const IR::Constant *value, const IR::Constant *mask,
309 const std::vector<const IR::Type::Bits *> &fieldTypes);
310
311 virtual IR::Vector<IR::Argument> *createApplyArguments(cstring n);
312
313 const IR::V1Control *ingress;
314 IR::ID ingressReference;
315
316 const IR::P4Control *verifyChecksums;
317 const IR::P4Control *updateChecksums;
318 const IR::P4Control *deparser;
320 const IR::Expression *latest;
321 const int defaultRegisterWidth = 32;
322
323 virtual void loadModel();
324 void createExterns();
325 void createTypes();
326 virtual const IR::P4Program *create(Util::SourceInfo info);
327};
328
329} // namespace P4V1
330
331#endif /* FRONTENDS_P4_FROMV1_0_PROGRAMSTRUCTURE_H_ */
Definition node.h:50
Definition vector.h:56
Definition callGraph.h:41
Definition coreLibrary.h:98
Definition frontends/p4/fromv1.0/programStructure.h:32
Information about the structure of a P4-14 program, used to convert it to a P4-16 program.
Definition frontends/p4/fromv1.0/programStructure.h:45
void populateOutputNames()
Definition frontends/p4/fromv1.0/programStructure.cpp:2634
virtual void createControls()
Definition frontends/p4/fromv1.0/programStructure.cpp:2325
std::map< const IR::MethodCallExpression *, const IR::Type_Header * > extractsSynthesized
Definition frontends/p4/fromv1.0/programStructure.h:179
std::map< cstring, const IR::Meter * > directMeters
Maps table name to direct meter.
Definition frontends/p4/fromv1.0/programStructure.h:159
virtual const IR::Vector< IR::Expression > * listIndexes(cstring type, cstring field) const
Definition frontends/p4/fromv1.0/programStructure.cpp:155
ordered_set< const IR::FieldList * > allFieldLists
Field lists that appear in the program.
Definition frontends/p4/fromv1.0/programStructure.h:163
static const IR::Annotations * addGlobalNameAnnotation(cstring name, const IR::Annotations *annos=nullptr)
Definition frontends/p4/fromv1.0/programStructure.cpp:91
virtual const IR::ParserState * convertParser(const IR::V1Parser *, IR::IndexedVector< IR::Declaration > *)
Definition frontends/p4/fromv1.0/programStructure.cpp:508
std::map< cstring, const IR::Type * > finalHeaderType
Definition frontends/p4/fromv1.0/programStructure.h:171
const IR::Expression * listIndex(const IR::Expression *fl) const
Definition frontends/p4/fromv1.0/programStructure.cpp:166
std::vector< const IR::Declaration * > localInstances
extra local instances to control created by primitive translation
Definition frontends/p4/fromv1.0/programStructure.h:200
std::map< cstring, cstring > registerLayoutType
Definition frontends/p4/fromv1.0/programStructure.h:174
cstring fieldListsEnum
Name of the serializable enum that holds one id for each field list.
Definition frontends/p4/fromv1.0/programStructure.h:183
const IR::Expression * latest
Represents 'latest' P4-14 construct.
Definition frontends/p4/fromv1.0/programStructure.h:320
Definition frontends/p4/fromv1.0/v1model.h:264
Definition source_file.h:123
Definition cstring.h:80
Definition ordered_set.h:30
Definition id.h:28