P4C
The P4 Compiler
Loading...
Searching...
No Matches
specializeGenericTypes.h
1/*
2Copyright 2020 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 FRONTENDS_P4_SPECIALIZEGENERICTYPES_H_
18#define FRONTENDS_P4_SPECIALIZEGENERICTYPES_H_
19
20#include "frontends/common/resolveReferences/referenceMap.h"
21#include "frontends/p4/typeChecking/typeChecker.h"
22#include "ir/ir.h"
23
24namespace P4 {
25
30 const IR::Type_Specialized *specialized;
32 const IR::Type_Declaration *declaration;
34 const IR::Type_StructLike *replacement;
40
41 TypeSpecialization(cstring name, const IR::Type_Specialized *specialized,
42 const IR::Type_Declaration *decl, const IR::Node *insertion,
43 const IR::Vector<IR::Type> *argTypes)
44 : name(name),
46 declaration(decl),
47 replacement(nullptr),
49 argumentTypes(argTypes) {
50 CHECK_NULL(specialized);
51 CHECK_NULL(decl);
52 CHECK_NULL(insertion);
53 CHECK_NULL(argTypes);
54 }
55 void dbprint(std::ostream &out) const override {
56 out << "Specializing:" << dbp(specialized) << " from " << dbp(declaration) << " as "
57 << dbp(replacement) << " inserted at " << dbp(insertion);
58 }
59};
60
62 TypeMap *typeMap;
63 // The map can have multiple keys pointing to the same value
65 // Keep track of the values in the above map which are already
66 // inserted in the program.
67 std::set<TypeSpecialization *> inserted;
68
69 void add(const IR::Type_Specialized *t, const IR::Type_StructLike *decl,
70 const IR::Node *insertion, NameGenerator *nameGen);
71 TypeSpecialization *get(const IR::Type_Specialized *t) const;
72 bool same(const TypeSpecialization *left, const IR::Type_Specialized *right) const;
73 void dbprint(std::ostream &out) const override {
74 for (auto it : map) {
75 out << dbp(it.first) << " => " << it.second << std::endl;
76 }
77 }
78 IR::Vector<IR::Node> *getSpecializations(const IR::Node *insertionPoint) {
79 IR::Vector<IR::Node> *result = nullptr;
80 for (auto s : map) {
81 if (inserted.find(s.second) != inserted.end()) continue;
82 if (s.second->insertion == insertionPoint) {
83 if (result == nullptr) result = new IR::Vector<IR::Node>();
84 LOG2("Will insert " << dbp(s.second->replacement) << " before "
85 << dbp(insertionPoint));
86 result->push_back(s.second->replacement);
87 inserted.emplace(s.second);
88 }
89 }
90 return result;
91 }
92};
93
98 TypeSpecializationMap *specMap;
100
101 public:
102 explicit FindTypeSpecializations(TypeSpecializationMap *specMap) : specMap(specMap) {
103 CHECK_NULL(specMap);
104 setName("FindTypeSpecializations");
105 }
106
107 void postorder(const IR::Type_Specialized *type) override;
108 profile_t init_apply(const IR::Node *node) override;
109};
110
116 TypeSpecializationMap *specMap;
117
118 public:
119 explicit CreateSpecializedTypes(TypeSpecializationMap *specMap) : specMap(specMap) {
120 CHECK_NULL(specMap);
121 setName("CreateSpecializedTypes");
122 }
123
124 const IR::Node *insert(const IR::Node *before);
125 const IR::Node *postorder(IR::Type_Declaration *type) override;
126 const IR::Node *postorder(IR::Declaration *decl) override { return insert(decl); }
127};
128
134 TypeSpecializationMap *specMap;
135
136 public:
137 explicit ReplaceTypeUses(TypeSpecializationMap *specMap) : specMap(specMap) {
138 setName("ReplaceTypeUses");
139 CHECK_NULL(specMap);
140 }
141 const IR::Node *postorder(IR::Type_Specialized *type) override;
142 const IR::Node *postorder(IR::StructExpression *expresison) override;
143};
144
163 TypeSpecializationMap specMap;
164
165 public:
166 explicit SpecializeGenericTypes(TypeMap *typeMap) {
167 passes.emplace_back(new PassRepeated({
168 new TypeChecking(nullptr, typeMap),
169 new FindTypeSpecializations(&specMap),
170 new CreateSpecializedTypes(&specMap),
171 // The previous pass has mutated some struct types
172 new ClearTypeMap(typeMap, true),
173 }));
174 passes.emplace_back(new TypeChecking(nullptr, typeMap));
175 passes.emplace_back(new ReplaceTypeUses(&specMap));
176 // The previous pass has invalidated the types of struct expressions
177 passes.emplace_back(new ClearTypeMap(typeMap, true));
178 specMap.typeMap = typeMap;
179 setName("SpecializeGenericTypes");
180 setStopOnError(true);
181 }
182};
183
185// Note: this pass is currently not used, but some
186// back-ends may find it useful.
188 public:
189 const IR::Node *postorder(IR::Type_StructLike *type) override {
190 if (!type->typeParameters->empty()) return nullptr;
191 return type;
192 }
193 const IR::Node *postorder(IR::Type_Stack *type) override {
194 if (type->elementType->is<IR::Type_Specialized>()) return nullptr;
195 return type;
196 }
197};
198
199} // namespace P4
200
201#endif /* FRONTENDS_P4_SPECIALIZEGENERICTYPES_H_ */
Definition typeChecker.h:32
Definition specializeGenericTypes.h:115
Definition specializeGenericTypes.h:97
Definition stringify.h:33
Definition node.h:95
Definition vector.h:58
Definition visitor.h:400
Definition referenceMap.h:36
Definition referenceMap.h:29
Definition pass_manager.h:145
Removes all structs or stacks that are generic.
Definition specializeGenericTypes.h:187
Definition specializeGenericTypes.h:133
Specializes each generic type by substituting type parameters.
Definition specializeGenericTypes.h:162
Definition visitor.h:424
Definition typeChecker.h:55
Definition typeMap.h:41
Definition visitor.h:78
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 specializeGenericTypes.h:26
const IR::Vector< IR::Type > * argumentTypes
Definition specializeGenericTypes.h:39
const IR::Type_StructLike * replacement
New synthesized type (created later)
Definition specializeGenericTypes.h:34
const IR::Type_Declaration * declaration
Declaration of specialized type, which will be replaced.
Definition specializeGenericTypes.h:32
const IR::Type_Specialized * specialized
Type that is being specialized.
Definition specializeGenericTypes.h:30
cstring name
Name to use for specialized type.
Definition specializeGenericTypes.h:28
const IR::Node * insertion
Insertion point.
Definition specializeGenericTypes.h:36
Definition specializeGenericTypes.h:61