P4C
The P4 Compiler
Loading...
Searching...
No Matches
flattenInterfaceStructs.h
1/*
2Copyright 2018 VMware, 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 MIDEND_FLATTENINTERFACESTRUCTS_H_
18#define MIDEND_FLATTENINTERFACESTRUCTS_H_
19
20#include "frontends/common/resolveReferences/resolveReferences.h"
21#include "frontends/p4/typeChecking/typeChecker.h"
22#include "ir/ir.h"
23#include "lib/cstring.h"
24
25namespace P4 {
26
32 public:
34
43 virtual bool keep(const IR::Annotation *) { return true; }
44};
45
66template <typename T>
67// T is the type of objects that will be replaced. E.g., IR::Type_Struct
69 StructTypeReplacement(const P4::TypeMap *typeMap, const IR::Type_StructLike *type,
72 flatten(typeMap, cstring::empty, type, type->annotations, vec, policy);
73 if (type->is<IR::Type_Struct>()) {
74 replacementType =
75 new IR::Type_Struct(type->srcInfo, type->name, IR::Annotations::empty, *vec);
76 } else if (type->is<IR::Type_Header>()) {
77 replacementType =
78 new IR::Type_Header(type->srcInfo, type->name, IR::Annotations::empty, *vec);
79 } else {
80 BUG("Unexpected type %1%", type);
81 }
82 }
83
84 // Maps nested field names to final field names.
85 // In our example this could be:
86 // .t.s.a -> _t_s_a0;
87 // .t.s.b -> _t_s_b1;
88 // .t.y -> _t_y2;
89 // .x -> _x3;
90 std::map<cstring, cstring> fieldNameRemap;
91 // Maps internal fields names to types.
92 // .t -> T
93 // .t.s -> S
94 std::map<cstring, const IR::Type_StructLike *> structFieldMap;
95 // Holds a new flat type
96 // struct M {
97 // bit _t_s_a0;
98 // bool _t_s_b1;
99 // bit<6> _t_y2;
100 // bit<3> _x3;
101 // }
102 const IR::Type *replacementType;
103 virtual void dbprint(std::ostream &out) const { out << replacementType; }
104
105 // Helper for constructor
106 void flatten(const P4::TypeMap *typeMap, cstring prefix, const IR::Type *type,
107 const IR::Annotations *annotations, IR::IndexedVector<IR::StructField> *fields,
109 // Drop name annotations
110 annotations = annotations->where(
111 [](const IR::Annotation *a) { return a->name != IR::Annotation::nameAnnotation; });
112 if (auto st = type->to<T>()) {
113 auto sannotations = st->annotations->where([policy](const IR::Annotation *annot) {
114 if (!policy) return false;
115 return policy->keep(annot);
116 });
117 structFieldMap.emplace(prefix, st);
118 for (auto f : st->fields) {
119 auto na = new IR::Annotations();
120 na->append(sannotations);
121 na->append(annotations);
122 na->append(f->annotations);
123 auto ft = typeMap->getType(f, true);
124 flatten(typeMap, prefix + "." + f->name, ft, na, fields, policy);
125 }
126 return;
127 }
128 cstring fieldName = prefix.replace('.', '_') + std::to_string(fieldNameRemap.size());
129 fieldNameRemap.emplace(prefix, fieldName);
130 fields->push_back(new IR::StructField(IR::ID(fieldName), annotations, type->getP4Type()));
131 LOG3("Flatten: " << type << " | " << prefix);
132 }
133
138 const IR::StructExpression *explode(const IR::Expression *root, cstring prefix) {
140 auto fieldType = ::P4::get(structFieldMap, prefix);
141 BUG_CHECK(fieldType, "No field for %1%", prefix);
142 for (auto f : fieldType->fields) {
143 cstring fieldName = prefix + "." + f->name.name;
144 auto newFieldname = ::P4::get(fieldNameRemap, fieldName);
145 const IR::Expression *expr;
146 if (!newFieldname.isNullOrEmpty()) {
147 expr = new IR::Member(root, newFieldname);
148 } else {
149 expr = explode(root, fieldName);
150 }
151 vec->push_back(new IR::NamedExpression(f->name, expr));
152 }
153 auto type = fieldType->getP4Type()->template to<IR::Type_Name>();
154 return new IR::StructExpression(root->srcInfo, type, type, *vec);
155 }
156};
157
163 P4::TypeMap *typeMap;
164
166
167 explicit NestedStructMap(P4::TypeMap *typeMap) : typeMap(typeMap) { CHECK_NULL(typeMap); }
168 void createReplacement(const IR::Type_Struct *type);
169 StructTypeReplacement<IR::Type_Struct> *getReplacement(const IR::Type *type) const {
170 return ::P4::get(replacement, type);
171 }
172 bool empty() const { return replacement.empty(); }
173};
174
180 NestedStructMap *map;
181
182 public:
183 explicit FindTypesToReplace(NestedStructMap *map) : map(map) {
184 setName("FindTypesToReplace");
185 CHECK_NULL(map);
186 }
187 bool preorder(const IR::Declaration_Instance *inst) override;
188};
189
233 NestedStructMap *replacementMap;
234 std::map<const IR::Parameter *, StructTypeReplacement<IR::Type_Struct> *> toReplace;
235
236 public:
237 explicit ReplaceStructs(NestedStructMap *sm) : replacementMap(sm) {
238 CHECK_NULL(sm);
239 setName("ReplaceStructs");
240 }
241
242 const IR::Node *preorder(IR::P4Program *program) override;
243 const IR::Node *postorder(IR::Member *expression) override;
244 const IR::Node *preorder(IR::P4Parser *parser) override;
245 const IR::Node *preorder(IR::P4Control *control) override;
246 const IR::Node *postorder(IR::Type_Struct *type) override;
247};
248
251
252 public:
253 explicit FlattenInterfaceStructs(TypeMap *typeMap) : sm(typeMap) {
254 passes.push_back(new TypeChecking(nullptr, typeMap));
255 passes.push_back(new FindTypesToReplace(&sm));
256 passes.push_back(new ReplaceStructs(&sm));
257 passes.push_back(new ClearTypeMap(typeMap));
258 setName("FlattenInterfaceStructs");
259 }
260};
261
262} // namespace P4
263
264#endif /* MIDEND_FLATTENINTERFACESTRUCTS_H_ */
Definition flattenInterfaceStructs.h:31
virtual bool keep(const IR::Annotation *)
Definition flattenInterfaceStructs.h:43
Definition typeChecker.h:32
Definition flattenInterfaceStructs.h:179
Definition flattenInterfaceStructs.h:249
Definition stringify.h:33
Definition node.h:52
Definition node.h:95
Definition visitor.h:400
Definition visitor.h:788
Definition ir/pass_manager.h:40
Definition flattenInterfaceStructs.h:232
Visitor mixin for looking up names in enclosing scopes from the Visitor::Context.
Definition resolveReferences.h:35
Definition visitor.h:424
Definition typeChecker.h:55
Definition typeMap.h:41
Definition cstring.h:85
Definition ordered_map.h:32
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
Definition id.h:28
Definition flattenInterfaceStructs.h:162
Definition flattenInterfaceStructs.h:68
const IR::StructExpression * explode(const IR::Expression *root, cstring prefix)
Definition flattenInterfaceStructs.h:138