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