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)
119 : policy(policy ? policy : new ConstantFoldingPolicy()),
120 refMap(refMap),
122 typesKnown(typeMap != nullptr),
124 visitDagOnce = true;
125 setName("DoConstantFolding");
126 assignmentTarget = false;
127 }
128
129 // If DeclarationLookup is not passed, then resolve by our own. We might
130 // need proper context for this
131 explicit DoConstantFolding(const TypeMap *typeMap, bool warnings = true,
132 ConstantFoldingPolicy *policy = nullptr)
133 : DoConstantFolding(this, typeMap, warnings, policy) {}
134
135 DoConstantFolding() : DoConstantFolding(nullptr, nullptr) {}
136
137 const IR::Node *postorder(IR::Declaration_Constant *d) override;
138 const IR::Node *postorder(IR::PathExpression *e) override;
139 const IR::Node *postorder(IR::Cmpl *e) override;
140 const IR::Node *postorder(IR::Neg *e) override;
141 const IR::Node *postorder(IR::UPlus *e) override;
142 const IR::Node *postorder(IR::LNot *e) override;
143 const IR::Node *postorder(IR::LAnd *e) override;
144 const IR::Node *postorder(IR::LOr *e) override;
145 const IR::Node *postorder(IR::Slice *e) override;
146 const IR::Node *postorder(IR::PlusSlice *e) override;
147 const IR::Node *postorder(IR::Add *e) override;
148 const IR::Node *postorder(IR::AddSat *e) override;
149 const IR::Node *postorder(IR::Sub *e) override;
150 const IR::Node *postorder(IR::SubSat *e) override;
151 const IR::Node *postorder(IR::Mul *e) override;
152 const IR::Node *postorder(IR::Div *e) override;
153 const IR::Node *postorder(IR::Mod *e) override;
154 const IR::Node *postorder(IR::BXor *e) override;
155 const IR::Node *postorder(IR::BAnd *e) override;
156 const IR::Node *postorder(IR::BOr *e) override;
157 const IR::Node *postorder(IR::Equ *e) override;
158 const IR::Node *postorder(IR::Neq *e) override;
159 const IR::Node *postorder(IR::Lss *e) override;
160 const IR::Node *postorder(IR::Grt *e) override;
161 const IR::Node *postorder(IR::Leq *e) override;
162 const IR::Node *postorder(IR::Geq *e) override;
163 const IR::Node *postorder(IR::Shl *e) override;
164 const IR::Node *postorder(IR::Shr *e) override;
165 const IR::Node *postorder(IR::Concat *e) override;
166 const IR::Node *postorder(IR::Member *e) override;
167 const IR::Node *postorder(IR::Cast *e) override;
168 const IR::Node *postorder(IR::Mux *e) override;
169 const IR::Node *postorder(IR::Type_Bits *type) override;
170 const IR::Node *postorder(IR::Type_Varbits *type) override;
171 const IR::Node *postorder(IR::SelectExpression *e) override;
172 const IR::Node *postorder(IR::IfStatement *statement) override;
173 const IR::Node *preorder(IR::AssignmentStatement *statement) override;
174 const IR::Node *preorder(IR::ArrayIndex *e) override;
175 const IR::Node *preorder(IR::SwitchCase *c) override;
176 const IR::BlockStatement *preorder(IR::BlockStatement *bs) override {
177 if (bs->annotations->getSingle("disable_optimization"_cs)) prune();
178 return bs;
179 }
180};
181
187 public:
189 : ConstantFolding(typeMap, true, nullptr, policy) {}
190
191 explicit ConstantFolding(ConstantFoldingPolicy *policy)
192 : ConstantFolding(nullptr, true, nullptr, policy) {}
193
194 explicit ConstantFolding(TypeMap *typeMap, bool warnings = true,
195 TypeChecking *typeChecking = nullptr,
196 ConstantFoldingPolicy *policy = nullptr) {
197 if (typeMap != nullptr) {
198 if (!typeChecking) typeChecking = new TypeChecking(nullptr, typeMap);
199 passes.push_back(typeChecking);
200 }
201 passes.push_back(new DoConstantFolding(typeMap, warnings, policy));
202 if (typeMap != nullptr) passes.push_back(new ClearTypeMap(typeMap));
203 setName("ConstantFolding");
204 }
205};
206
207} // namespace P4
208
209#endif /* COMMON_CONSTANTFOLDING_H_ */
Definition typeChecker.h:32
Definition constantFolding.h:186
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:834
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:974
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 ir/pass_manager.h:40
Visitor mixin for looking up names in enclosing scopes from the Visitor::Context.
Definition resolveReferences.h:35
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