37class ProgramStructure {
42 class NamedObjectInfo {
46 std::unordered_map<cstring, int> *allNames;
47 std::map<cstring, T> nameToObject;
48 std::map<T, cstring> objectToNewName;
52 friend class NamedObjectInfo;
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) {}
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]);
73 explicit NamedObjectInfo(std::unordered_map<cstring, int> *allNames) : allNames(allNames) {}
75 if (objectToNewName.find(obj) != objectToNewName.end()) {
77 LOG3(
" already emplaced obj " << obj);
81 nameToObject.emplace(obj->name, obj);
84 if (allNames ==
nullptr || (allNames->find(obj->name) == allNames->end())) {
87 newName = cstring::make_unique(*allNames, obj->name, allNames->at(obj->name),
'_');
89 if (allNames !=
nullptr) allNames->insert({newName, 0});
90 LOG3(
"Discovered " << obj <<
" named " << newName);
91 objectToNewName.emplace(obj, newName);
94 T get(
cstring name)
const { return ::P4::get(nameToObject, name); }
97 return ::P4::get(objectToNewName,
object, object->name.name);
101 bool contains(
cstring name)
const {
return nameToObject.find(name) != nameToObject.end(); }
102 iterator begin() {
return iterator(nameToObject.begin(), objectToNewName); }
105 allNames->erase(name);
106 auto obj = get(name);
107 objectToNewName.erase(obj);
108 nameToObject.erase(name);
112 std::set<cstring> included_files;
116 virtual ~ProgramStructure() =
default;
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;
151 std::map<cstring, IR::Vector<IR::Expression>> extracts;
152 std::map<cstring, cstring> directCounters;
155 std::map<const IR::Meter *, const IR::Declaration_Instance *> meterMap;
156 std::map<cstring, const IR::Declaration_Instance *> counterMap;
160 std::map<const IR::V1Table *, const IR::V1Control *> tableMapping;
161 std::map<const IR::V1Table *, const IR::Apply *> tableInvocation;
176 std::map<cstring, const IR::ParserState *> parserEntryPoints;
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;
200 const IR::Parameter *parserPacketIn =
nullptr;
201 const IR::Parameter *parserHeadersOut =
nullptr;
207 virtual const IR::Statement *convertPrimitive(
const IR::Primitive *primitive);
208 virtual void checkHeaderType(
const IR::Type_StructLike *hrd,
bool toStruct);
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,
225 virtual const IR::Declaration_Instance *convert(
const IR::CounterOrMeter *cm,
cstring newName);
226 virtual const IR::Declaration_Instance *convertActionProfile(
const IR::ActionProfile *,
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,
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();
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();
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);
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;
274 bool isFieldInList(
cstring type,
cstring field,
const IR::FieldList *fl)
const;
280 const IR::Expression *
listIndex(
const IR::Expression *fl)
const;
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);
288 const IR::V1Control *ingress;
291 const IR::P4Control *verifyChecksums;
292 const IR::P4Control *updateChecksums;
293 const IR::P4Control *deparser;
296 const int defaultRegisterWidth = 32;
298 virtual void loadModel();
299 void createExterns();