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
78 const IR::Expression *getConstant(const IR::Expression *expr) const;
79
81 const IR::Constant *cast(const IR::Constant *node, unsigned base, const IR::Type_Bits *type,
82 bool noWarning = false) const;
83
85 const IR::Node *binary(const IR::Operation_Binary *op,
86 std::function<big_int(big_int, big_int)> func, bool saturating = false);
89 const IR::Node *compare(const IR::Operation_Binary *op);
90
92 const IR::Node *shift(const IR::Operation_Binary *op);
93
95 enum class Result { Yes, No, DontKnow };
96
106 Result setContains(const IR::Expression *keySet, const IR::Expression *constant) const;
107
108 public:
110 ConstantFoldingPolicy *policy = nullptr)
111 : policy(policy ? policy : new ConstantFoldingPolicy()),
112 refMap(refMap),
114 typesKnown(typeMap != nullptr),
116 visitDagOnce = true;
117 setName("DoConstantFolding");
118 assignmentTarget = false;
119 }
120
121 // If DeclarationLookup is not passed, then resolve by our own. We might
122 // need proper context for this
123 explicit DoConstantFolding(const TypeMap *typeMap, bool warnings = true,
124 ConstantFoldingPolicy *policy = nullptr)
125 : DoConstantFolding(this, typeMap, warnings, policy) {}
126
127 DoConstantFolding() : DoConstantFolding(nullptr, nullptr) {}
128
129 const IR::Node *postorder(IR::Declaration_Constant *d) override;
130 const IR::Node *postorder(IR::PathExpression *e) override;
131 const IR::Node *postorder(IR::Cmpl *e) override;
132 const IR::Node *postorder(IR::Neg *e) override;
133 const IR::Node *postorder(IR::UPlus *e) override;
134 const IR::Node *postorder(IR::LNot *e) override;
135 const IR::Node *postorder(IR::LAnd *e) override;
136 const IR::Node *postorder(IR::LOr *e) override;
137 const IR::Node *postorder(IR::Slice *e) override;
138 const IR::Node *postorder(IR::PlusSlice *e) override;
139 const IR::Node *postorder(IR::Add *e) override;
140 const IR::Node *postorder(IR::AddSat *e) override;
141 const IR::Node *postorder(IR::Sub *e) override;
142 const IR::Node *postorder(IR::SubSat *e) override;
143 const IR::Node *postorder(IR::Mul *e) override;
144 const IR::Node *postorder(IR::Div *e) override;
145 const IR::Node *postorder(IR::Mod *e) override;
146 const IR::Node *postorder(IR::BXor *e) override;
147 const IR::Node *postorder(IR::BAnd *e) override;
148 const IR::Node *postorder(IR::BOr *e) override;
149 const IR::Node *postorder(IR::Equ *e) override;
150 const IR::Node *postorder(IR::Neq *e) override;
151 const IR::Node *postorder(IR::Lss *e) override;
152 const IR::Node *postorder(IR::Grt *e) override;
153 const IR::Node *postorder(IR::Leq *e) override;
154 const IR::Node *postorder(IR::Geq *e) override;
155 const IR::Node *postorder(IR::Shl *e) override;
156 const IR::Node *postorder(IR::Shr *e) override;
157 const IR::Node *postorder(IR::Concat *e) override;
158 const IR::Node *postorder(IR::Member *e) override;
159 const IR::Node *postorder(IR::Cast *e) override;
160 const IR::Node *postorder(IR::Mux *e) override;
161 const IR::Node *postorder(IR::Type_Bits *type) override;
162 const IR::Node *postorder(IR::Type_Varbits *type) override;
163 const IR::Node *postorder(IR::SelectExpression *e) override;
164 const IR::Node *postorder(IR::IfStatement *statement) override;
165 const IR::Node *preorder(IR::BaseAssignmentStatement *statement) override;
166 const IR::Node *preorder(IR::ArrayIndex *e) override;
167 const IR::Node *preorder(IR::SwitchCase *c) override;
168 const IR::BlockStatement *preorder(IR::BlockStatement *bs) override {
169 if (bs->hasAnnotation(IR::Annotation::disableOptimizationAnnotation)) prune();
170 return bs;
171 }
172};
173
178class ConstantFolding : public PassManager {
179 public:
180 ConstantFolding(TypeMap *typeMap, ConstantFoldingPolicy *policy)
181 : ConstantFolding(typeMap, true, nullptr, policy) {}
182
183 explicit ConstantFolding(ConstantFoldingPolicy *policy)
184 : ConstantFolding(nullptr, true, nullptr, policy) {}
185
186 explicit ConstantFolding(TypeMap *typeMap, bool warnings = true,
187 TypeChecking *typeChecking = nullptr,
188 ConstantFoldingPolicy *policy = nullptr) {
189 if (typeMap != nullptr) {
190 if (!typeChecking) typeChecking = new TypeChecking(nullptr, typeMap);
191 passes.push_back(typeChecking);
192 }
193 passes.push_back(new DoConstantFolding(typeMap, warnings, policy));
194 if (typeMap != nullptr) passes.push_back(new ClearTypeMap(typeMap));
195 setName("ConstantFolding");
196 }
197};
198
199} // namespace P4
200
201#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:95
const DeclarationLookup * refMap
Definition constantFolding.h:59
const IR::Node * shift(const IR::Operation_Binary *op)
Statically evaluate shift operation e.
Definition constantFolding.cpp:835
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:492
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:976
bool typesKnown
Set to true iff typeMap is not nullptr.
Definition constantFolding.h:66
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:333
const IR::Expression * getConstant(const IR::Expression *expr) const
Definition constantFolding.cpp:44
const IR::Node * compare(const IR::Operation_Binary *op)
Definition constantFolding.cpp:424
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