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/resolveReferences.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, public Inspector, public ResolutionContext {
70 TypeMap *typeMap;
71
72 public:
73 explicit IsValid(TypeMap *typeMap) : typeMap(typeMap) { CHECK_NULL(typeMap); }
74 bool isSimple(const IR::Expression *expression, const Visitor::Context *ctxt);
75};
76
81class IsMask : public IsLikeLeftValue {
82 public:
83 bool isSimple(const IR::Expression *expression, const Visitor::Context *ctxt) {
84 if (auto mask = expression->to<IR::BAnd>()) {
85 if (mask->right->is<IR::Constant>())
86 expression = mask->left;
87 else if (mask->left->is<IR::Constant>())
88 expression = mask->right;
89 }
90 return IsLikeLeftValue::isSimple(expression, ctxt);
91 }
92};
93
98class OrPolicy : public KeyIsSimple {
99 KeyIsSimple *left;
100 KeyIsSimple *right;
101
102 public:
103 OrPolicy(KeyIsSimple *left, KeyIsSimple *right) : left(left), right(right) {
104 CHECK_NULL(left);
105 CHECK_NULL(right);
106 }
107 bool isSimple(const IR::Expression *expression, const Visitor::Context *ctxt) {
108 return left->isSimple(expression, ctxt) || right->isSimple(expression, ctxt);
109 }
110};
111
142class DoSimplifyKey : public Transform {
143 MinimalNameGenerator nameGen;
144 TypeMap *typeMap;
145 KeyIsSimple *key_policy;
146 std::map<const IR::P4Table *, TableInsertions *> toInsert;
147
148 public:
149 DoSimplifyKey(TypeMap *typeMap, KeyIsSimple *key_policy)
150 : typeMap(typeMap), key_policy(key_policy) {
151 CHECK_NULL(typeMap);
152 CHECK_NULL(key_policy);
153 setName("DoSimplifyKey");
154 }
155
156 Visitor::profile_t init_apply(const IR::Node *node) override {
157 auto rv = Transform::init_apply(node);
158 node->apply(nameGen);
159
160 return rv;
161 }
162
163 const IR::Node *doStatement(const IR::Statement *statement, const IR::Expression *expression);
164
165 // These should be all kinds of statements that may contain a table apply
166 // after the program has been simplified
167 const IR::Node *postorder(IR::MethodCallStatement *statement) override {
168 return doStatement(statement, statement->methodCall);
169 }
170 const IR::Node *postorder(IR::IfStatement *statement) override {
171 return doStatement(statement, statement->condition);
172 }
173 const IR::Node *postorder(IR::SwitchStatement *statement) override {
174 return doStatement(statement, statement->expression);
175 }
176 const IR::Node *postorder(IR::AssignmentStatement *statement) override {
177 return doStatement(statement, statement->right);
178 }
179 const IR::Node *postorder(IR::KeyElement *element) override;
180 const IR::Node *postorder(IR::P4Table *table) override;
181};
182
187class SimplifyKey : public PassManager {
188 public:
189 SimplifyKey(TypeMap *typeMap, KeyIsSimple *key_policy, TypeChecking *typeChecking = nullptr) {
190 if (!typeChecking) typeChecking = new TypeChecking(nullptr, typeMap);
191 passes.push_back(typeChecking);
192 passes.push_back(new DoSimplifyKey(typeMap, key_policy));
193 setName("SimplifyKey");
194 }
195};
196
197} // namespace P4
198
199#endif /* MIDEND_SIMPLIFYKEY_H_ */
Definition simplifyKey.h:142
Definition node.h:95
Definition visitor.h:400
Definition simplifyKey.h:41
Definition simplifyKey.h:81
Definition simplifyKey.h:69
Definition simplifyKey.h:31
Definition referenceMap.h:36
Definition simplifyKey.h:98
Definition ir/pass_manager.h:40
Visitor mixin for looking up names in enclosing scopes from the Visitor::Context.
Definition resolveReferences.h:35
Definition simplifyKey.h:187
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