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