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