P4C
The P4 Compiler
Loading...
Searching...
No Matches
strengthReduction.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_P4_STRENGTHREDUCTION_H_
18#define FRONTENDS_P4_STRENGTHREDUCTION_H_
19
20#include "frontends/common/resolveReferences/referenceMap.h"
21#include "frontends/p4/sideEffects.h"
22#include "frontends/p4/typeChecking/typeChecker.h"
23#include "frontends/p4/typeMap.h"
24#include "ir/ir.h"
25
26namespace P4 {
27
28using namespace literals;
29
30class StrengthReductionPolicy {
31 public:
32 StrengthReductionPolicy() {}
33 StrengthReductionPolicy(bool enableSubConstToAddTransform,
37
41
45};
46
64class DoStrengthReduction final : public Transform {
65 protected:
66 TypeMap *typeMap = nullptr;
68
70 bool isOne(const IR::Expression *expr) const;
72 bool isZero(const IR::Expression *expr) const;
74 bool isTrue(const IR::Expression *expr) const;
76 bool isFalse(const IR::Expression *expr) const;
78 bool isAllOnes(const IR::Expression *expr) const;
81 int isPowerOf2(const IR::Expression *expr) const;
82
86 bool hasSideEffects(const IR::Expression *expr) const {
87 return SideEffects::check(expr, this, nullptr, nullptr);
88 }
89
90 public:
92 : typeMap(typeMap), policy(policy ? policy : new StrengthReductionPolicy()) {
93 visitDagOnce = true;
94 setName("StrengthReduction");
95 }
96
97 DoStrengthReduction() : DoStrengthReduction(nullptr, nullptr) {}
98
99 using Transform::postorder;
100
101 const IR::Node *postorder(IR::Cmpl *expr) override;
102 const IR::Node *postorder(IR::BAnd *expr) override;
103 const IR::Node *postorder(IR::BOr *expr) override;
104 const IR::Node *postorder(IR::Equ *expr) override;
105 const IR::Node *postorder(IR::Neq *expr) override;
106 const IR::Node *relation(IR::Operation_Relation *expr, bool grt, bool eq);
107 const IR::Node *postorder(IR::Geq *expr) override { return relation(expr, true, true); }
108 const IR::Node *postorder(IR::Grt *expr) override { return relation(expr, true, false); }
109 const IR::Node *postorder(IR::Leq *expr) override { return relation(expr, false, true); }
110 const IR::Node *postorder(IR::Lss *expr) override { return relation(expr, false, false); }
111 const IR::Node *postorder(IR::BXor *expr) override;
112 const IR::Node *postorder(IR::LAnd *expr) override;
113 const IR::Node *postorder(IR::LOr *expr) override;
114 const IR::Node *postorder(IR::LNot *expr) override;
115 const IR::Node *postorder(IR::Sub *expr) override;
116 const IR::Node *postorder(IR::SubSat *expr) override;
117 const IR::Node *postorder(IR::Add *expr) override;
118 const IR::Node *postorder(IR::AddSat *expr) override;
119 const IR::Node *postorder(IR::UPlus *expr) override;
120 const IR::Node *postorder(IR::Shl *expr) override;
121 const IR::Node *postorder(IR::Shr *expr) override;
122 const IR::Node *postorder(IR::Mul *expr) override;
123 const IR::Node *postorder(IR::Div *expr) override;
124 const IR::Node *postorder(IR::Mod *expr) override;
125 const IR::Node *postorder(IR::Mux *expr) override;
126 const IR::Node *postorder(IR::Slice *expr) override;
127 const IR::Node *postorder(IR::PlusSlice *expr) override;
128 const IR::Node *postorder(IR::Cast *expr) override;
129 const IR::Node *postorder(IR::Mask *expr) override;
130 const IR::Node *postorder(IR::Range *expr) override;
131 const IR::Node *postorder(IR::Concat *expr) override;
132 const IR::Node *postorder(IR::ArrayIndex *expr) override;
133
134 const IR::BlockStatement *preorder(IR::BlockStatement *bs) override {
135 // FIXME: Do we need to check for expression, so we'd be able to fine tune, e.g.
136 // @disable_optimization("strength_reduce")
137 if (bs->hasAnnotation(IR::Annotation::disableOptimizationAnnotation)) prune();
138 return bs;
139 }
140};
141
142class StrengthReduction : public PassManager {
143 public:
144 explicit StrengthReduction(TypeMap *typeMap, TypeChecking *typeChecking = nullptr,
145 StrengthReductionPolicy *policy = nullptr) {
146 if (typeMap != nullptr) {
147 if (!typeChecking) typeChecking = new TypeChecking(nullptr, typeMap, true);
148 passes.push_back(typeChecking);
149 }
150 passes.push_back(new DoStrengthReduction(typeMap, policy));
151 }
152
153 explicit StrengthReduction(TypeMap *typeMap, StrengthReductionPolicy *policy)
154 : StrengthReduction(typeMap, nullptr, policy) {}
155};
156
157} // namespace P4
158
159#endif /* FRONTENDS_P4_STRENGTHREDUCTION_H_ */
Definition strengthReduction.h:64
const IR::Node * postorder(IR::Cmpl *expr) override
Definition strengthReduction.cpp:71
bool isZero(const IR::Expression *expr) const
Definition strengthReduction.cpp:29
bool isFalse(const IR::Expression *expr) const
Definition strengthReduction.cpp:44
bool isAllOnes(const IR::Expression *expr) const
Definition strengthReduction.cpp:60
bool isTrue(const IR::Expression *expr) const
Definition strengthReduction.cpp:38
bool isOne(const IR::Expression *expr) const
Definition strengthReduction.cpp:23
bool hasSideEffects(const IR::Expression *expr) const
Definition strengthReduction.h:86
int isPowerOf2(const IR::Expression *expr) const
Definition strengthReduction.cpp:50
static bool check(const IR::Expression *expression, const Visitor *calledBy, TypeMap *typeMap=nullptr, const Visitor::Context *ctxt=nullptr)
Definition sideEffects.h:90
Definition strengthReduction.h:30
bool enableNarrowingCastToSliceTransform
Definition strengthReduction.h:44
bool enableSubConstToAddTransform
Definition strengthReduction.h:40
Definition visitor.h:442
Definition typeChecker.h:55
Definition typeMap.h:41
Definition cstring.h:80
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24