46class ProgramStructure {
51 class NamedObjectInfo {
55 std::unordered_map<cstring, int> *allNames;
56 std::map<cstring, T> nameToObject;
57 std::map<T, cstring> objectToNewName;
61 friend class NamedObjectInfo;
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) {}
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]);
82 explicit NamedObjectInfo(std::unordered_map<cstring, int> *allNames) : allNames(allNames) {}
84 if (objectToNewName.find(obj) != objectToNewName.end()) {
86 LOG3(
" already emplaced obj " << obj);
90 nameToObject.emplace(obj->name, obj);
93 if (allNames ==
nullptr || (allNames->find(obj->name) == allNames->end())) {
96 newName = cstring::make_unique(*allNames, obj->name, allNames->at(obj->name),
'_');
98 if (allNames !=
nullptr) allNames->insert({newName, 0});
99 LOG3(
"Discovered " << obj <<
" named " << newName);
100 objectToNewName.emplace(obj, newName);
103 T get(
cstring name)
const { return ::P4::get(nameToObject, name); }
106 return ::P4::get(objectToNewName,
object, object->name.name);
110 bool contains(
cstring name)
const {
return nameToObject.find(name) != nameToObject.end(); }
111 iterator begin() {
return iterator(nameToObject.begin(), objectToNewName); }
114 allNames->erase(name);
115 auto obj = get(name);
116 objectToNewName.erase(obj);
117 nameToObject.erase(name);
121 std::set<cstring> included_files;
125 virtual ~ProgramStructure() =
default;
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;
160 std::map<cstring, IR::Vector<IR::Expression>> extracts;
161 std::map<cstring, cstring> directCounters;
164 std::map<const IR::Meter *, const IR::Declaration_Instance *> meterMap;
165 std::map<cstring, const IR::Declaration_Instance *> counterMap;
169 std::map<const IR::V1Table *, const IR::V1Control *> tableMapping;
170 std::map<const IR::V1Table *, const IR::Apply *> tableInvocation;
185 std::map<cstring, const IR::ParserState *> parserEntryPoints;
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;
209 const IR::Parameter *parserPacketIn =
nullptr;
210 const IR::Parameter *parserHeadersOut =
nullptr;
216 virtual const IR::Statement *convertPrimitive(
const IR::Primitive *primitive);
217 virtual void checkHeaderType(
const IR::Type_StructLike *hrd,
bool toStruct);
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,
234 virtual const IR::Declaration_Instance *convert(
const IR::CounterOrMeter *cm,
cstring newName);
235 virtual const IR::Declaration_Instance *convertActionProfile(
const IR::ActionProfile *,
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,
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();
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();
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);
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;
283 bool isFieldInList(
cstring type,
cstring field,
const IR::FieldList *fl)
const;
289 const IR::Expression *
listIndex(
const IR::Expression *fl)
const;
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);
297 const IR::V1Control *ingress;
300 const IR::P4Control *verifyChecksums;
301 const IR::P4Control *updateChecksums;
302 const IR::P4Control *deparser;
305 const int defaultRegisterWidth = 32;
307 virtual void loadModel();
308 void createExterns();