P4C
The P4 Compiler
Loading...
Searching...
No Matches
simplifyKey.h
1/*
2 * Copyright 2016 VMware, Inc.
3 * SPDX-FileCopyrightText: 2016 VMware, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef MIDEND_SIMPLIFYKEY_H_
9#define MIDEND_SIMPLIFYKEY_H_
10
11#include "frontends/common/resolveReferences/resolveReferences.h"
12#include "frontends/p4/sideEffects.h"
13#include "frontends/p4/typeChecking/typeChecker.h"
14#include "ir/ir.h"
15
16namespace P4 {
17
23 public:
24 virtual ~KeyIsSimple() {}
25 virtual bool isSimple(const IR::Expression *expression, const Visitor::Context *) = 0;
26};
27
32class IsLikeLeftValue : public KeyIsSimple, public Inspector {
33 protected:
34 bool simple = false;
35
36 public:
37 IsLikeLeftValue() { setName("IsLikeLeftValue"); }
38
39 void postorder(const IR::Expression *) override {
40 // all other expressions are complicated
41 simple = false;
42 }
43 void postorder(const IR::Member *) override {}
44 void postorder(const IR::PathExpression *) override {}
45 void postorder(const IR::ArrayIndex *) override {}
46 profile_t init_apply(const IR::Node *root) override {
47 simple = true;
48 return Inspector::init_apply(root);
49 }
50
51 bool isSimple(const IR::Expression *expression, const Visitor::Context *) override {
52 (void)expression->apply(*this);
53 return simple;
54 }
55};
56
60class IsValid : public KeyIsSimple, public Inspector, public ResolutionContext {
61 TypeMap *typeMap;
62
63 public:
64 explicit IsValid(TypeMap *typeMap) : typeMap(typeMap) { CHECK_NULL(typeMap); }
65 bool isSimple(const IR::Expression *expression, const Visitor::Context *ctxt);
66};
67
72class IsMask : public IsLikeLeftValue {
73 public:
74 bool isSimple(const IR::Expression *expression, const Visitor::Context *ctxt) {
75 if (auto mask = expression->to<IR::BAnd>()) {
76 if (mask->right->is<IR::Constant>())
77 expression = mask->left;
78 else if (mask->left->is<IR::Constant>())
79 expression = mask->right;
80 }
81 return IsLikeLeftValue::isSimple(expression, ctxt);
82 }
83};
84
89class OrPolicy : public KeyIsSimple {
90 KeyIsSimple *left;
91 KeyIsSimple *right;
92
93 public:
94 OrPolicy(KeyIsSimple *left, KeyIsSimple *right) : left(left), right(right) {
95 CHECK_NULL(left);
96 CHECK_NULL(right);
97 }
98 bool isSimple(const IR::Expression *expression, const Visitor::Context *ctxt) {
99 return left->isSimple(expression, ctxt) || right->isSimple(expression, ctxt);
100 }
101};
102
133class DoSimplifyKey : public Transform {
134 MinimalNameGenerator nameGen;
135 TypeMap *typeMap;
136 KeyIsSimple *key_policy;
137 std::map<const IR::P4Table *, TableInsertions *> toInsert;
138
139 public:
140 DoSimplifyKey(TypeMap *typeMap, KeyIsSimple *key_policy)
141 : typeMap(typeMap), key_policy(key_policy) {
142 CHECK_NULL(typeMap);
143 CHECK_NULL(key_policy);
144 setName("DoSimplifyKey");
145 }
146
147 Visitor::profile_t init_apply(const IR::Node *node) override {
148 auto rv = Transform::init_apply(node);
149 node->apply(nameGen);
150
151 return rv;
152 }
153
154 const IR::Node *doStatement(const IR::Statement *statement, const IR::Expression *expression);
155
156 // These should be all kinds of statements that may contain a table apply
157 // after the program has been simplified
158 const IR::Node *postorder(IR::MethodCallStatement *statement) override {
159 return doStatement(statement, statement->methodCall);
160 }
161 const IR::Node *postorder(IR::IfStatement *statement) override {
162 return doStatement(statement, statement->condition);
163 }
164 const IR::Node *postorder(IR::SwitchStatement *statement) override {
165 return doStatement(statement, statement->expression);
166 }
167 const IR::Node *postorder(IR::BaseAssignmentStatement *statement) override {
168 return doStatement(statement, statement->right);
169 }
170 const IR::Node *postorder(IR::KeyElement *element) override;
171 const IR::Node *postorder(IR::P4Table *table) override;
172};
173
178class SimplifyKey : public PassManager {
179 public:
180 SimplifyKey(TypeMap *typeMap, KeyIsSimple *key_policy, TypeChecking *typeChecking = nullptr) {
181 if (!typeChecking) typeChecking = new TypeChecking(nullptr, typeMap);
182 passes.push_back(typeChecking);
183 passes.push_back(new DoSimplifyKey(typeMap, key_policy));
184 setName("SimplifyKey");
185 }
186};
187
188} // namespace P4
189
190#endif /* MIDEND_SIMPLIFYKEY_H_ */
Definition simplifyKey.h:133
Definition node.h:53
Definition visitor.h:418
Definition simplifyKey.h:72
Definition simplifyKey.h:22
Definition referenceMap.h:36
Definition visitor.h:442
Definition typeChecker.h:55
Definition typeMap.h:32
Definition visitor.h:78
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13