P4C
The P4 Compiler
Loading...
Searching...
No Matches
constantFolding.h
1/*
2Copyright 2013-present Barefoot Networks, 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 COMMON_CONSTANTFOLDING_H_
18#define COMMON_CONSTANTFOLDING_H_
19
20#include "frontends/common/resolveReferences/referenceMap.h"
21#include "frontends/common/resolveReferences/resolveReferences.h"
22#include "frontends/p4/typeChecking/typeChecker.h"
23#include "ir/ir.h"
24
25namespace P4 {
26
27using namespace literals;
28
36 public:
38 virtual const IR::Node *hook(Visitor &, IR::PathExpression *) { return nullptr; }
39};
40
62 protected:
64
68
72
75
78
80 std::map<const IR::Declaration_Constant *, const IR::Expression *> constants;
81 // True if we are processing a left side of an assignment; we should not
82 // we substituting constants there.
83 bool assignmentTarget;
84
86 const IR::Expression *getConstant(const IR::Expression *expr) const;
87
89 const IR::Constant *cast(const IR::Constant *node, unsigned base,
90 const IR::Type_Bits *type) const;
91
93 const IR::Node *binary(const IR::Operation_Binary *op,
94 std::function<big_int(big_int, big_int)> func, bool saturating = false);
97 const IR::Node *compare(const IR::Operation_Binary *op);
98
100 const IR::Node *shift(const IR::Operation_Binary *op);
101
103 enum class Result { Yes, No, DontKnow };
104
114 Result setContains(const IR::Expression *keySet, const IR::Expression *constant) const;
115
116 public:
118 ConstantFoldingPolicy *policy = nullptr)
120 if (policy) {
121 this->policy = policy;
122 } else {
123 this->policy = new ConstantFoldingPolicy();
124 }
125 visitDagOnce = true;
126 setName("DoConstantFolding");
127 assignmentTarget = false;
128 }
129
130 // If DeclarationLookup is not passed, then resolve by our own.
131 explicit DoConstantFolding(const TypeMap *typeMap, bool warnings = true,
132 ConstantFoldingPolicy *policy = nullptr)
133 : DoConstantFolding(this, typeMap, warnings, policy) {}
134
135 const IR::Node *postorder(IR::Declaration_Constant *d) override;
136 const IR::Node *postorder(IR::PathExpression *e) override;
137 const IR::Node *postorder(IR::Cmpl *e) override;
138 const IR::Node *postorder(IR::Neg *e) override;
139 const IR::Node *postorder(IR::UPlus *e) override;
140 const IR::Node *postorder(IR::LNot *e) override;
141 const IR::Node *postorder(IR::LAnd *e) override;
142 const IR::Node *postorder(IR::LOr *e) override;
143 const IR::Node *postorder(IR::Slice *e) override;
144 const IR::Node *postorder(IR::Add *e) override;
145 const IR::Node *postorder(IR::AddSat *e) override;
146 const IR::Node *postorder(IR::Sub *e) override;
147 const IR::Node *postorder(IR::SubSat *e) override;
148 const IR::Node *postorder(IR::Mul *e) override;
149 const IR::Node *postorder(IR::Div *e) override;
150 const IR::Node *postorder(IR::Mod *e) override;
151 const IR::Node *postorder(IR::BXor *e) override;
152 const IR::Node *postorder(IR::BAnd *e) override;
153 const IR::Node *postorder(IR::BOr *e) override;
154 const IR::Node *postorder(IR::Equ *e) override;
155 const IR::Node *postorder(IR::Neq *e) override;
156 const IR::Node *postorder(IR::Lss *e) override;
157 const IR::Node *postorder(IR::Grt *e) override;
158 const IR::Node *postorder(IR::Leq *e) override;
159 const IR::Node *postorder(IR::Geq *e) override;
160 const IR::Node *postorder(IR::Shl *e) override;
161 const IR::Node *postorder(IR::Shr *e) override;
162 const IR::Node *postorder(IR::Concat *e) override;
163 const IR::Node *postorder(IR::Member *e) override;
164 const IR::Node *postorder(IR::Cast *e) override;
165 const IR::Node *postorder(IR::Mux *e) override;
166 const IR::Node *postorder(IR::Type_Bits *type) override;
167 const IR::Node *postorder(IR::Type_Varbits *type) override;
168 const IR::Node *postorder(IR::SelectExpression *e) override;
169 const IR::Node *postorder(IR::IfStatement *statement) override;
170 const IR::Node *preorder(IR::AssignmentStatement *statement) override;
171 const IR::Node *preorder(IR::ArrayIndex *e) override;
172 const IR::Node *preorder(IR::SwitchCase *c) override;
173 const IR::BlockStatement *preorder(IR::BlockStatement *bs) override {
174 if (bs->annotations->getSingle("disable_optimization"_cs)) prune();
175 return bs;
176 }
177};
178
184 public:
186 : ConstantFolding(refMap, typeMap, true, nullptr, policy) {}
187
188 ConstantFolding(ReferenceMap *refMap, TypeMap *typeMap, bool warnings = true,
189 TypeChecking *typeChecking = nullptr, ConstantFoldingPolicy *policy = nullptr) {
190 if (typeMap != nullptr) {
191 if (!typeChecking) typeChecking = new TypeChecking(refMap, typeMap);
192 passes.push_back(typeChecking);
193 }
194 passes.push_back(new DoConstantFolding(refMap, typeMap, warnings, policy));
195 if (typeMap != nullptr) passes.push_back(new ClearTypeMap(typeMap));
196 setName("ConstantFolding");
197 }
198
200 : ConstantFolding(typeMap, true, nullptr, policy) {}
201
202 explicit ConstantFolding(ConstantFoldingPolicy *policy)
203 : ConstantFolding(nullptr, true, nullptr, policy) {}
204
205 explicit ConstantFolding(TypeMap *typeMap, bool warnings = true,
206 TypeChecking *typeChecking = nullptr,
207 ConstantFoldingPolicy *policy = nullptr) {
208 if (typeMap != nullptr) {
209 if (!typeChecking) typeChecking = new TypeChecking(nullptr, typeMap);
210 passes.push_back(typeChecking);
211 }
212 passes.push_back(new DoConstantFolding(typeMap, warnings, policy));
213 if (typeMap != nullptr) passes.push_back(new ClearTypeMap(typeMap));
214 setName("ConstantFolding");
215 }
216};
217
218} // namespace P4
219
220#endif /* COMMON_CONSTANTFOLDING_H_ */
Definition typeChecker.h:32
Definition constantFolding.h:183
Definition constantFolding.h:35
virtual const IR::Node * hook(Visitor &, IR::PathExpression *)
The default hook does not modify anything.
Definition constantFolding.h:38
Definition referenceMap.h:57
statically evaluates many constant expressions.
Definition constantFolding.h:61
Result
Result type for setContains.
Definition constantFolding.h:103
const DeclarationLookup * refMap
Definition constantFolding.h:67
const IR::Node * shift(const IR::Operation_Binary *op)
Statically evaluate shift operation e.
Definition constantFolding.cpp:789
std::map< const IR::Declaration_Constant *, const IR::Expression * > constants
Maps declaration constants to constant expressions.
Definition constantFolding.h:80
const IR::Node * binary(const IR::Operation_Binary *op, std::function< big_int(big_int, big_int)> func, bool saturating=false)
Statically evaluate binary operation e implemented by func.
Definition constantFolding.cpp:501
const TypeMap * typeMap
Definition constantFolding.h:71
bool warnings
If true then emit warnings.
Definition constantFolding.h:77
Result setContains(const IR::Expression *keySet, const IR::Expression *constant) const
Definition constantFolding.cpp:929
bool typesKnown
Set to true iff typeMap is not nullptr.
Definition constantFolding.h:74
const IR::Constant * cast(const IR::Constant *node, unsigned base, const IR::Type_Bits *type) const
Statically cast constant node to type represented in the specified base.
Definition constantFolding.cpp:342
const IR::Expression * getConstant(const IR::Expression *expr) const
Definition constantFolding.cpp:55
const IR::Node * compare(const IR::Operation_Binary *op)
Definition constantFolding.cpp:433
Definition node.h:95
Definition pass_manager.h:40
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Visitor mixin for looking up names in enclosing scopes from the Visitor::Context.
Definition resolveReferences.h:33
Definition visitor.h:424
Definition typeChecker.h:55
Definition typeMap.h:41
Definition visitor.h:75
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24