P4C
The P4 Compiler
Loading...
Searching...
No Matches
simplifyKey.h
1/*
2Copyright 2016 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_SIMPLIFYKEY_H_
18#define MIDEND_SIMPLIFYKEY_H_
19
20#include "frontends/common/resolveReferences/referenceMap.h"
21#include "frontends/p4/sideEffects.h"
22#include "frontends/p4/typeChecking/typeChecker.h"
23#include "ir/ir.h"
24
25namespace P4 {
26
32 public:
33 virtual ~KeyIsSimple() {}
34 virtual bool isSimple(const IR::Expression *expression, const Visitor::Context *) = 0;
35};
36
41class IsLikeLeftValue : public KeyIsSimple, public Inspector {
42 protected:
43 bool simple = false;
44
45 public:
46 IsLikeLeftValue() { setName("IsLikeLeftValue"); }
47
48 void postorder(const IR::Expression *) override {
49 // all other expressions are complicated
50 simple = false;
51 }
52 void postorder(const IR::Member *) override {}
53 void postorder(const IR::PathExpression *) override {}
54 void postorder(const IR::ArrayIndex *) override {}
55 profile_t init_apply(const IR::Node *root) override {
56 simple = true;
57 return Inspector::init_apply(root);
58 }
59
60 bool isSimple(const IR::Expression *expression, const Visitor::Context *) override {
61 (void)expression->apply(*this);
62 return simple;
63 }
64};
65
69class IsValid : public KeyIsSimple {
70 ReferenceMap *refMap;
71 TypeMap *typeMap;
72
73 public:
74 IsValid(ReferenceMap *refMap, TypeMap *typeMap) : refMap(refMap), typeMap(typeMap) {
75 CHECK_NULL(refMap);
76 CHECK_NULL(typeMap);
77 }
78 bool isSimple(const IR::Expression *expression, const Visitor::Context *);
79};
80
85class IsMask : public IsLikeLeftValue {
86 public:
87 bool isSimple(const IR::Expression *expression, const Visitor::Context *ctxt) {
88 if (auto mask = expression->to<IR::BAnd>()) {
89 if (mask->right->is<IR::Constant>())
90 expression = mask->left;
91 else if (mask->left->is<IR::Constant>())
92 expression = mask->right;
93 }
94 return IsLikeLeftValue::isSimple(expression, ctxt);
95 }
96};
97
102class OrPolicy : public KeyIsSimple {
103 KeyIsSimple *left;
104 KeyIsSimple *right;
105
106 public:
107 OrPolicy(KeyIsSimple *left, KeyIsSimple *right) : left(left), right(right) {
108 CHECK_NULL(left);
109 CHECK_NULL(right);
110 }
111 bool isSimple(const IR::Expression *expression, const Visitor::Context *ctxt) {
112 return left->isSimple(expression, ctxt) || right->isSimple(expression, ctxt);
113 }
114};
115
146class DoSimplifyKey : public Transform {
147 ReferenceMap *refMap;
148 TypeMap *typeMap;
149 KeyIsSimple *key_policy;
150 std::map<const IR::P4Table *, TableInsertions *> toInsert;
151
152 public:
153 DoSimplifyKey(ReferenceMap *refMap, TypeMap *typeMap, KeyIsSimple *key_policy)
154 : refMap(refMap), typeMap(typeMap), key_policy(key_policy) {
155 CHECK_NULL(refMap);
156 CHECK_NULL(typeMap);
157 CHECK_NULL(key_policy);
158 setName("DoSimplifyKey");
159 }
160 const IR::Node *doStatement(const IR::Statement *statement, const IR::Expression *expression);
161
162 // These should be all kinds of statements that may contain a table apply
163 // after the program has been simplified
164 const IR::Node *postorder(IR::MethodCallStatement *statement) override {
165 return doStatement(statement, statement->methodCall);
166 }
167 const IR::Node *postorder(IR::IfStatement *statement) override {
168 return doStatement(statement, statement->condition);
169 }
170 const IR::Node *postorder(IR::SwitchStatement *statement) override {
171 return doStatement(statement, statement->expression);
172 }
173 const IR::Node *postorder(IR::AssignmentStatement *statement) override {
174 return doStatement(statement, statement->right);
175 }
176 const IR::Node *postorder(IR::KeyElement *element) override;
177 const IR::Node *postorder(IR::P4Table *table) override;
178};
179
184class SimplifyKey : public PassManager {
185 public:
186 SimplifyKey(ReferenceMap *refMap, TypeMap *typeMap, KeyIsSimple *key_policy,
187 TypeChecking *typeChecking = nullptr) {
188 if (!typeChecking) typeChecking = new TypeChecking(refMap, typeMap);
189 passes.push_back(typeChecking);
190 passes.push_back(new DoSimplifyKey(refMap, typeMap, key_policy));
191 setName("SimplifyKey");
192 }
193};
194
195} // namespace P4
196
197#endif /* MIDEND_SIMPLIFYKEY_H_ */
Definition simplifyKey.h:146
Definition node.h:95
Definition visitor.h:400
Definition simplifyKey.h:41
Definition simplifyKey.h:85
Definition simplifyKey.h:69
Definition simplifyKey.h:31
Definition simplifyKey.h:102
Definition pass_manager.h:40
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Definition simplifyKey.h:184
Definition visitor.h:424
Definition typeChecker.h:55
Definition typeMap.h:41
Definition visitor.h:78
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
Definition visitor.h:47