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 FRONTENDS_COMMON_CONSTANTFOLDING_H_
18#define FRONTENDS_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:
37 virtual ~ConstantFoldingPolicy() = default;
39 virtual const IR::Node *hook(Visitor &, IR::PathExpression *) { return nullptr; }
40};
41
62class DoConstantFolding : public Transform, public ResolutionContext {
63 protected:
65
69
73
76
79
81 std::map<const IR::Declaration_Constant *, const IR::Expression *> constants;
82 // True if we are processing a left side of an assignment; we should not
83 // we substituting constants there.
84 bool assignmentTarget;
85
88 const IR::Type *resolveType(const IR::Type *t);
89
91 const IR::Expression *getConstant(const IR::Expression *expr) const;
92
94 const IR::Constant *cast(const IR::Constant *node, unsigned base, const IR::Type_Bits *type,
95 bool noWarning = false) const;
96
98 const IR::Node *binary(const IR::Operation_Binary *op,
99 std::function<big_int(big_int, big_int)> func, bool saturating = false);
102 const IR::Node *compare(const IR::Operation_Binary *op);
103
105 const IR::Node *shift(const IR::Operation_Binary *op);
106
108 enum class Result { Yes, No, DontKnow };
109
119 Result setContains(const IR::Expression *keySet, const IR::Expression *constant) const;
120
121 public:
123 ConstantFoldingPolicy *policy = nullptr)
124 : policy(policy ? policy : new ConstantFoldingPolicy()),
125 refMap(refMap),
127 typesKnown(typeMap != nullptr),
129 visitDagOnce = true;
130 setName("DoConstantFolding");
131 assignmentTarget = false;
132 }
133
134 // If DeclarationLookup is not passed, then resolve by our own. We might
135 // need proper context for this
136 explicit DoConstantFolding(const TypeMap *typeMap, bool warnings = true,
137 ConstantFoldingPolicy *policy = nullptr)
138 : DoConstantFolding(this, typeMap, warnings, policy) {}
139
140 DoConstantFolding() : DoConstantFolding(nullptr, nullptr) {}
141
142 const IR::Node *postorder(IR::Declaration_Constant *d) override;
143 const IR::Node *postorder(IR::PathExpression *e) override;
144 const IR::Node *postorder(IR::Cmpl *e) override;
145 const IR::Node *postorder(IR::Neg *e) override;
146 const IR::Node *postorder(IR::UPlus *e) override;
147 const IR::Node *postorder(IR::LNot *e) override;
148 const IR::Node *postorder(IR::LAnd *e) override;
149 const IR::Node *postorder(IR::LOr *e) override;
150 const IR::Node *postorder(IR::Slice *e) override;
151 const IR::Node *postorder(IR::PlusSlice *e) override;
152 const IR::Node *postorder(IR::Add *e) override;
153 const IR::Node *postorder(IR::AddSat *e) override;
154 const IR::Node *postorder(IR::Sub *e) override;
155 const IR::Node *postorder(IR::SubSat *e) override;
156 const IR::Node *postorder(IR::Mul *e) override;
157 const IR::Node *postorder(IR::Div *e) override;
158 const IR::Node *postorder(IR::Mod *e) override;
159 const IR::Node *postorder(IR::BXor *e) override;
160 const IR::Node *postorder(IR::BAnd *e) override;
161 const IR::Node *postorder(IR::BOr *e) override;
162 const IR::Node *postorder(IR::Equ *e) override;
163 const IR::Node *postorder(IR::Neq *e) override;
164 const IR::Node *postorder(IR::Lss *e) override;
165 const IR::Node *postorder(IR::Grt *e) override;
166 const IR::Node *postorder(IR::Leq *e) override;
167 const IR::Node *postorder(IR::Geq *e) override;
168 const IR::Node *postorder(IR::Shl *e) override;
169 const IR::Node *postorder(IR::Shr *e) override;
170 const IR::Node *postorder(IR::Concat *e) override;
171 const IR::Node *postorder(IR::Member *e) override;
172 const IR::Node *postorder(IR::Cast *e) override;
173 const IR::Node *postorder(IR::Mux *e) override;
174 const IR::Node *postorder(IR::Type_Bits *type) override;
175 const IR::Node *postorder(IR::Type_Varbits *type) override;
176 const IR::Node *postorder(IR::SelectExpression *e) override;
177 const IR::Node *postorder(IR::IfStatement *statement) override;
178 const IR::Node *preorder(IR::BaseAssignmentStatement *statement) override;
179 const IR::Node *preorder(IR::ArrayIndex *e) override;
180 const IR::Node *preorder(IR::SwitchCase *c) override;
181 const IR::BlockStatement *preorder(IR::BlockStatement *bs) override {
182 if (bs->hasAnnotation(IR::Annotation::disableOptimizationAnnotation)) prune();
183 return bs;
184 }
185};
186
191class ConstantFolding : public PassManager {
192 public:
193 ConstantFolding(TypeMap *typeMap, ConstantFoldingPolicy *policy)
194 : ConstantFolding(typeMap, true, nullptr, policy) {}
195
196 explicit ConstantFolding(ConstantFoldingPolicy *policy)
197 : ConstantFolding(nullptr, true, nullptr, policy) {}
198
199 explicit ConstantFolding(TypeMap *typeMap, bool warnings = true,
200 TypeChecking *typeChecking = nullptr,
201 ConstantFoldingPolicy *policy = nullptr) {
202 if (typeMap != nullptr) {
203 if (!typeChecking) typeChecking = new TypeChecking(nullptr, typeMap);
204 passes.push_back(typeChecking);
205 }
206 passes.push_back(new DoConstantFolding(typeMap, warnings, policy));
207 if (typeMap != nullptr) passes.push_back(new ClearTypeMap(typeMap));
208 setName("ConstantFolding");
209 }
210};
211
212} // namespace P4
213
214#endif /* FRONTENDS_COMMON_CONSTANTFOLDING_H_ */
Definition typeChecker.h:32
Definition constantFolding.h:35
virtual const IR::Node * hook(Visitor &, IR::PathExpression *)
The default hook does not modify anything.
Definition constantFolding.h:39
Definition referenceMap.h:57
statically evaluates many constant expressions.
Definition constantFolding.h:62
Result
Result type for setContains.
Definition constantFolding.h:108
const DeclarationLookup * refMap
Definition constantFolding.h:68
const IR::Node * shift(const IR::Operation_Binary *op)
Statically evaluate shift operation e.
Definition constantFolding.cpp:862
std::map< const IR::Declaration_Constant *, const IR::Expression * > constants
Maps declaration constants to constant expressions.
Definition constantFolding.h:81
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:519
const TypeMap * typeMap
Definition constantFolding.h:72
bool warnings
If true then emit warnings.
Definition constantFolding.h:78
Result setContains(const IR::Expression *keySet, const IR::Expression *constant) const
Definition constantFolding.cpp:1010
bool typesKnown
Set to true iff typeMap is not nullptr.
Definition constantFolding.h:75
const IR::Type * resolveType(const IR::Type *t)
Definition constantFolding.cpp:55
const IR::Constant * cast(const IR::Constant *node, unsigned base, const IR::Type_Bits *type, bool noWarning=false) const
Statically cast constant node to type represented in the specified base.
Definition constantFolding.cpp:360
const IR::Expression * getConstant(const IR::Expression *expr) const
Definition constantFolding.cpp:68
const IR::Node * compare(const IR::Operation_Binary *op)
Definition constantFolding.cpp:451
Definition node.h:53
Definition visitor.h:442
Definition typeChecker.h:55
Definition typeMap.h:32
Definition visitor.h:75
Definition typeMap.h:32
Definition cstring.h:80
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13