P4C
The P4 Compiler
Loading...
Searching...
No Matches
constantFolding.h
1/*
2 * SPDX-FileCopyrightText: 2013 Barefoot Networks, Inc.
3 * Copyright 2013-present Barefoot Networks, Inc.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8#ifndef FRONTENDS_COMMON_CONSTANTFOLDING_H_
9#define FRONTENDS_COMMON_CONSTANTFOLDING_H_
10
11#include "frontends/common/resolveReferences/referenceMap.h"
12#include "frontends/common/resolveReferences/resolveReferences.h"
13#include "frontends/p4/typeChecking/typeChecker.h"
14#include "ir/ir.h"
15
16namespace P4 {
17
18using namespace literals;
19
27 public:
28 virtual ~ConstantFoldingPolicy() = default;
30 virtual const IR::Node *hook(Visitor &, IR::PathExpression *) { return nullptr; }
31};
32
53class DoConstantFolding : public Transform, public ResolutionContext {
54 protected:
56
60
64
67
70
72 std::map<const IR::Declaration_Constant *, const IR::Expression *> constants;
73 // True if we are processing a left side of an assignment; we should not
74 // we substituting constants there.
75 bool assignmentTarget;
76
79 const IR::Type *resolveType(const IR::Type *t);
80
82 const IR::Expression *getConstant(const IR::Expression *expr) const;
83
85 const IR::Constant *cast(const IR::Constant *node, unsigned base, const IR::Type_Bits *type,
86 bool noWarning = false) const;
87
89 const IR::Node *binary(const IR::Operation_Binary *op,
90 std::function<big_int(big_int, big_int)> func, bool saturating = false);
93 const IR::Node *compare(const IR::Operation_Binary *op);
94
96 const IR::Node *shift(const IR::Operation_Binary *op);
97
99 enum class Result { Yes, No, DontKnow };
100
110 Result setContains(const IR::Expression *keySet, const IR::Expression *constant) const;
111
112 public:
114 ConstantFoldingPolicy *policy = nullptr)
115 : policy(policy ? policy : new ConstantFoldingPolicy()),
116 refMap(refMap),
118 typesKnown(typeMap != nullptr),
120 visitDagOnce = true;
121 setName("DoConstantFolding");
122 assignmentTarget = false;
123 }
124
125 // If DeclarationLookup is not passed, then resolve by our own. We might
126 // need proper context for this
127 explicit DoConstantFolding(const TypeMap *typeMap, bool warnings = true,
128 ConstantFoldingPolicy *policy = nullptr)
129 : DoConstantFolding(this, typeMap, warnings, policy) {}
130
131 DoConstantFolding() : DoConstantFolding(nullptr, nullptr) {}
132
133 const IR::Node *postorder(IR::Declaration_Constant *d) override;
134 const IR::Node *postorder(IR::PathExpression *e) override;
135 const IR::Node *postorder(IR::Cmpl *e) override;
136 const IR::Node *postorder(IR::Neg *e) override;
137 const IR::Node *postorder(IR::UPlus *e) override;
138 const IR::Node *postorder(IR::LNot *e) override;
139 const IR::Node *postorder(IR::LAnd *e) override;
140 const IR::Node *postorder(IR::LOr *e) override;
141 const IR::Node *postorder(IR::Slice *e) override;
142 const IR::Node *postorder(IR::PlusSlice *e) override;
143 const IR::Node *postorder(IR::Add *e) override;
144 const IR::Node *postorder(IR::AddSat *e) override;
145 const IR::Node *postorder(IR::Sub *e) override;
146 const IR::Node *postorder(IR::SubSat *e) override;
147 const IR::Node *postorder(IR::Mul *e) override;
148 const IR::Node *postorder(IR::Div *e) override;
149 const IR::Node *postorder(IR::Mod *e) override;
150 const IR::Node *postorder(IR::BXor *e) override;
151 const IR::Node *postorder(IR::BAnd *e) override;
152 const IR::Node *postorder(IR::BOr *e) override;
153 const IR::Node *postorder(IR::Equ *e) override;
154 const IR::Node *postorder(IR::Neq *e) override;
155 const IR::Node *postorder(IR::Lss *e) override;
156 const IR::Node *postorder(IR::Grt *e) override;
157 const IR::Node *postorder(IR::Leq *e) override;
158 const IR::Node *postorder(IR::Geq *e) override;
159 const IR::Node *postorder(IR::Shl *e) override;
160 const IR::Node *postorder(IR::Shr *e) override;
161 const IR::Node *postorder(IR::Concat *e) override;
162 const IR::Node *postorder(IR::Member *e) override;
163 const IR::Node *postorder(IR::Cast *e) override;
164 const IR::Node *postorder(IR::Mux *e) override;
165 const IR::Node *postorder(IR::Type_Bits *type) override;
166 const IR::Node *postorder(IR::Type_Varbits *type) override;
167 const IR::Node *postorder(IR::SelectExpression *e) override;
168 const IR::Node *postorder(IR::IfStatement *statement) override;
169 const IR::Node *preorder(IR::BaseAssignmentStatement *statement) override;
170 const IR::Node *preorder(IR::ArrayIndex *e) override;
171 const IR::Node *preorder(IR::SwitchCase *c) override;
172 const IR::BlockStatement *preorder(IR::BlockStatement *bs) override {
173 if (bs->hasAnnotation(IR::Annotation::disableOptimizationAnnotation)) prune();
174 return bs;
175 }
176};
177
182class ConstantFolding : public PassManager {
183 public:
184 ConstantFolding(TypeMap *typeMap, ConstantFoldingPolicy *policy)
185 : ConstantFolding(typeMap, true, nullptr, policy) {}
186
187 explicit ConstantFolding(ConstantFoldingPolicy *policy)
188 : ConstantFolding(nullptr, true, nullptr, policy) {}
189
190 explicit ConstantFolding(TypeMap *typeMap, bool warnings = true,
191 TypeChecking *typeChecking = nullptr,
192 ConstantFoldingPolicy *policy = nullptr) {
193 if (typeMap != nullptr) {
194 if (!typeChecking) typeChecking = new TypeChecking(nullptr, typeMap);
195 passes.push_back(typeChecking);
196 }
197 passes.push_back(new DoConstantFolding(typeMap, warnings, policy));
198 if (typeMap != nullptr) passes.push_back(new ClearTypeMap(typeMap));
199 setName("ConstantFolding");
200 }
201};
202
203} // namespace P4
204
205#endif /* FRONTENDS_COMMON_CONSTANTFOLDING_H_ */
Definition typeChecker.h:23
Definition constantFolding.h:26
virtual const IR::Node * hook(Visitor &, IR::PathExpression *)
The default hook does not modify anything.
Definition constantFolding.h:30
Definition referenceMap.h:48
statically evaluates many constant expressions.
Definition constantFolding.h:53
Result
Result type for setContains.
Definition constantFolding.h:99
const DeclarationLookup * refMap
Definition constantFolding.h:59
const IR::Node * shift(const IR::Operation_Binary *op)
Statically evaluate shift operation e.
Definition constantFolding.cpp:851
std::map< const IR::Declaration_Constant *, const IR::Expression * > constants
Maps declaration constants to constant expressions.
Definition constantFolding.h:72
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:508
const TypeMap * typeMap
Definition constantFolding.h:63
bool warnings
If true then emit warnings.
Definition constantFolding.h:69
Result setContains(const IR::Expression *keySet, const IR::Expression *constant) const
Definition constantFolding.cpp:999
bool typesKnown
Set to true iff typeMap is not nullptr.
Definition constantFolding.h:66
const IR::Type * resolveType(const IR::Type *t)
Definition constantFolding.cpp:44
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:349
const IR::Expression * getConstant(const IR::Expression *expr) const
Definition constantFolding.cpp:57
const IR::Node * compare(const IR::Operation_Binary *op)
Definition constantFolding.cpp:440
Definition node.h:44
Definition visitor.h:433
Definition typeChecker.h:46
Definition typeMap.h:32
Definition visitor.h:66
Definition typeMap.h:32
Definition cstring.h:71
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13