P4C
The P4 Compiler
Loading...
Searching...
No Matches
strengthReduction.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_P4_STRENGTHREDUCTION_H_
9#define FRONTENDS_P4_STRENGTHREDUCTION_H_
10
11#include "frontends/common/resolveReferences/referenceMap.h"
12#include "frontends/p4/sideEffects.h"
13#include "frontends/p4/typeChecking/typeChecker.h"
14#include "frontends/p4/typeMap.h"
15#include "ir/ir.h"
16
17namespace P4 {
18
19using namespace literals;
20
21class StrengthReductionPolicy {
22 public:
23 StrengthReductionPolicy() {}
24 StrengthReductionPolicy(bool enableSubConstToAddTransform,
28
32
36};
37
55class DoStrengthReduction final : public Transform {
56 protected:
57 TypeMap *typeMap = nullptr;
59
61 bool isOne(const IR::Expression *expr) const;
63 bool isZero(const IR::Expression *expr) const;
65 bool isTrue(const IR::Expression *expr) const;
67 bool isFalse(const IR::Expression *expr) const;
69 bool isAllOnes(const IR::Expression *expr) const;
72 int isPowerOf2(const IR::Expression *expr) const;
73
77 bool hasSideEffects(const IR::Expression *expr) const {
78 return SideEffects::check(expr, this, nullptr, nullptr);
79 }
80
81 public:
83 : typeMap(typeMap), policy(policy ? policy : new StrengthReductionPolicy()) {
84 visitDagOnce = true;
85 setName("StrengthReduction");
86 }
87
88 DoStrengthReduction() : DoStrengthReduction(nullptr, nullptr) {}
89
90 using Transform::postorder;
91
92 const IR::Node *postorder(IR::Cmpl *expr) override;
93 const IR::Node *postorder(IR::BAnd *expr) override;
94 const IR::Node *postorder(IR::BOr *expr) override;
95 const IR::Node *postorder(IR::Equ *expr) override;
96 const IR::Node *postorder(IR::Neq *expr) override;
97 const IR::Node *relation(IR::Operation_Relation *expr, bool grt, bool eq);
98 const IR::Node *postorder(IR::Geq *expr) override { return relation(expr, true, true); }
99 const IR::Node *postorder(IR::Grt *expr) override { return relation(expr, true, false); }
100 const IR::Node *postorder(IR::Leq *expr) override { return relation(expr, false, true); }
101 const IR::Node *postorder(IR::Lss *expr) override { return relation(expr, false, false); }
102 const IR::Node *postorder(IR::BXor *expr) override;
103 const IR::Node *postorder(IR::LAnd *expr) override;
104 const IR::Node *postorder(IR::LOr *expr) override;
105 const IR::Node *postorder(IR::LNot *expr) override;
106 const IR::Node *postorder(IR::Sub *expr) override;
107 const IR::Node *postorder(IR::SubSat *expr) override;
108 const IR::Node *postorder(IR::Add *expr) override;
109 const IR::Node *postorder(IR::AddSat *expr) override;
110 const IR::Node *postorder(IR::UPlus *expr) override;
111 const IR::Node *postorder(IR::Shl *expr) override;
112 const IR::Node *postorder(IR::Shr *expr) override;
113 const IR::Node *postorder(IR::Mul *expr) override;
114 const IR::Node *postorder(IR::Div *expr) override;
115 const IR::Node *postorder(IR::Mod *expr) override;
116 const IR::Node *postorder(IR::Mux *expr) override;
117 const IR::Node *postorder(IR::Slice *expr) override;
118 const IR::Node *postorder(IR::PlusSlice *expr) override;
119 const IR::Node *postorder(IR::Cast *expr) override;
120 const IR::Node *postorder(IR::Mask *expr) override;
121 const IR::Node *postorder(IR::Range *expr) override;
122 const IR::Node *postorder(IR::Concat *expr) override;
123 const IR::Node *postorder(IR::ArrayIndex *expr) override;
124
125 const IR::BlockStatement *preorder(IR::BlockStatement *bs) override {
126 // FIXME: Do we need to check for expression, so we'd be able to fine tune, e.g.
127 // @disable_optimization("strength_reduce")
128 if (bs->hasAnnotation(IR::Annotation::disableOptimizationAnnotation)) prune();
129 return bs;
130 }
131};
132
133class StrengthReduction : public PassManager {
134 public:
135 explicit StrengthReduction(TypeMap *typeMap, TypeChecking *typeChecking = nullptr,
136 StrengthReductionPolicy *policy = nullptr) {
137 if (typeMap != nullptr) {
138 if (!typeChecking) typeChecking = new TypeChecking(nullptr, typeMap, true);
139 passes.push_back(typeChecking);
140 }
141 passes.push_back(new DoStrengthReduction(typeMap, policy));
142 }
143
144 explicit StrengthReduction(TypeMap *typeMap, StrengthReductionPolicy *policy)
145 : StrengthReduction(typeMap, nullptr, policy) {}
146};
147
148} // namespace P4
149
150#endif /* FRONTENDS_P4_STRENGTHREDUCTION_H_ */
Definition strengthReduction.h:55
const IR::Node * postorder(IR::Cmpl *expr) override
Definition strengthReduction.cpp:60
bool isZero(const IR::Expression *expr) const
Definition strengthReduction.cpp:18
bool isFalse(const IR::Expression *expr) const
Definition strengthReduction.cpp:33
bool isAllOnes(const IR::Expression *expr) const
Definition strengthReduction.cpp:49
bool isTrue(const IR::Expression *expr) const
Definition strengthReduction.cpp:27
bool isOne(const IR::Expression *expr) const
Definition strengthReduction.cpp:12
bool hasSideEffects(const IR::Expression *expr) const
Definition strengthReduction.h:77
int isPowerOf2(const IR::Expression *expr) const
Definition strengthReduction.cpp:39
static bool check(const IR::Expression *expression, const Visitor *calledBy, TypeMap *typeMap=nullptr, const Visitor::Context *ctxt=nullptr)
Definition sideEffects.h:81
Definition strengthReduction.h:21
bool enableNarrowingCastToSliceTransform
Definition strengthReduction.h:35
bool enableSubConstToAddTransform
Definition strengthReduction.h:31
Definition visitor.h:433
Definition typeChecker.h:46
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