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;
36 const IR::Node *insertion;
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 ReferenceMap *refMap;
63 TypeMap *typeMap;
64 // The map can have multiple keys pointing to the same value
66 // Keep track of the values in the above map which are already
67 // inserted in the program.
68 std::set<TypeSpecialization *> inserted;
69
70 void add(const IR::Type_Specialized *t, const IR::Type_StructLike *decl,
71 const IR::Node *insertion);
72 TypeSpecialization *get(const IR::Type_Specialized *t) const;
73 bool same(const TypeSpecialization *left, const IR::Type_Specialized *right) const;
74 void dbprint(std::ostream &out) const override {
75 for (auto it : map) {
76 out << dbp(it.first) << " => " << it.second << std::endl;
77 }
78 }
79 IR::Vector<IR::Node> *getSpecializations(const IR::Node *insertionPoint) {
80 IR::Vector<IR::Node> *result = nullptr;
81 for (auto s : map) {
82 if (inserted.find(s.second) != inserted.end()) continue;
83 if (s.second->insertion == insertionPoint) {
84 if (result == nullptr) result = new IR::Vector<IR::Node>();
85 LOG2("Will insert " << dbp(s.second->replacement) << " before "
86 << dbp(insertionPoint));
87 result->push_back(s.second->replacement);
88 inserted.emplace(s.second);
89 }
90 }
91 return result;
92 }
93};
94
98class FindTypeSpecializations : public Inspector {
99 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};
109
114class CreateSpecializedTypes : public Transform {
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
132class ReplaceTypeUses : public Transform {
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
161class SpecializeGenericTypes : public PassRepeated {
162 TypeSpecializationMap specMap;
163
164 public:
165 SpecializeGenericTypes(ReferenceMap *refMap, TypeMap *typeMap) {
166 passes.emplace_back(new PassRepeated({
167 new TypeChecking(refMap, 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(refMap, 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.refMap = refMap;
178 specMap.typeMap = typeMap;
179 setName("SpecializeGenericTypes");
180 }
181};
182
184// Note: this pass is currently not used, but some
185// back-ends may find it useful.
186class RemoveGenericTypes : public Transform {
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 source_file.h:38
Definition externInstance.h:33
Definition typeChecker.h:37
Definition specializeGenericTypes.h:114
Definition specializeGenericTypes.h:98
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
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 typeChecker.h:60
Definition typeMap.h:42
Definition cstring.h:72
Definition ordered_map.h:30
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