P4C
The P4 Compiler
Loading...
Searching...
No Matches
simplify_nested_if.h
1
26#include <stack>
27
28#include "backends/tofino/bf-p4c/device.h"
29#include "backends/tofino/bf-p4c/midend/path_linearizer.h"
30#include "backends/tofino/bf-p4c/midend/type_categories.h"
31#include "backends/tofino/bf-p4c/midend/type_checker.h"
32#include "frontends/common/resolveReferences/resolveReferences.h"
33#include "frontends/p4/simplify.h"
34#include "frontends/p4/strengthReduction.h"
35#include "frontends/p4/typeChecking/typeChecker.h"
36#include "frontends/p4/typeMap.h"
37#include "ir/ir.h"
38#include "ir/pattern.h"
39
40#ifndef _BACKENDS_TOFINO_BF_P4C_MIDEND_SIMPLIFY_NESTED_IF_H_
41#define _BACKENDS_TOFINO_BF_P4C_MIDEND_SIMPLIFY_NESTED_IF_H_
42
43namespace P4 {
44
49 public:
50 virtual ~SkipControlPolicy() {}
55 virtual bool convert(const IR::P4Control *control) const = 0;
56};
57
62 public:
64 bool convert(const IR::P4Control *control) const override {
65 return control->is<IR::BFN::TnaDeparser>();
66 }
67};
68
73 SkipControlPolicy *policy;
75 std::vector<const IR::Expression *> stack_;
76 std::vector<int> *mirrorType, *resubmitType, *digestType;
77 std::map<const IR::Statement *, std::vector<const IR::Expression *>> extraStmts;
78
79 public:
80 explicit DoSimplifyNestedIf(SkipControlPolicy *policy) : policy(policy) {
81 int size = 16;
82 if (Device::currentDevice() == Device::TOFINO) {
83 size = 8;
84 }
85 mirrorType = new std::vector<int>(size);
86 resubmitType = new std::vector<int>(size);
87 digestType = new std::vector<int>(size);
88 CHECK_NULL(policy);
89 }
90
91 const IR::Node *preorder(IR::IfStatement *statement) override;
92 const IR::Node *preorder(IR::P4Control *control) override;
93 void setExtraStmts(std::vector<int> *typeVec, const IR::Statement *stmt,
94 const IR::Expression *condition);
95 std::vector<int> *checkTypeAndGetVec(const IR::Statement *stmt);
96 void addInArray(std::vector<int> *typeVec, const IR::Expression *condition,
97 const IR::IfStatement *ifstmt);
98};
99
104 public:
106 virtual void reset() = 0;
107 virtual bool check(const IR::Expression *) = 0;
108};
109
114 ReferenceMap *refMap;
115 TypeMap *typeMap;
116 const std::set<cstring> *valid_fields;
117 std::set<cstring> unique_fields;
118
119 public:
120 UniqueAndValidDest(ReferenceMap *refMap, TypeMap *typeMap,
121 const std::set<cstring> *valid_fields)
122 : refMap(refMap), typeMap(typeMap), valid_fields(valid_fields) {
123 CHECK_NULL(refMap);
124 CHECK_NULL(typeMap);
125 CHECK_NULL(valid_fields);
126 }
127
128 void reset() override { unique_fields.clear(); }
129 bool check(const IR::Expression *dest) override {
131 dest->apply(path);
132 if (!path.linearPath) {
133 error("Destination %1% is too complex ", dest);
134 return false;
135 }
136
137 auto *param = BFN::getContainingParameter(*path.linearPath, refMap);
138 auto *paramType = typeMap->getType(param);
139 if (!BFN::isIntrinsicMetadataType(paramType)) {
140 error("Destination %1% must be intrinsic metadata ", dest);
141 return false;
142 }
143
144 if (auto mem = path.linearPath->components[0]->to<IR::Member>()) {
145 if (!valid_fields->count(mem->member.name)) {
146 error(
147 "Invalid field name %1%, the valid fields to use are "
148 "digest_type, resubmit_type and mirror_type");
149 }
150 }
151
152 unique_fields.insert(path.linearPath->to_cstring());
153
154 if (unique_fields.size() != 1) return false;
155
156 return true;
157 }
158};
159
174 SkipControlPolicy *skip;
175
176 bitvec constants;
177 std::stack<const IR::Expression *> stack_;
178 const IR::Expression *unique_dest = nullptr;
179
180 public:
182 : policy(policy), skip(skip) {
183 CHECK_NULL(policy);
184 CHECK_NULL(skip);
185 }
186
187 void do_equ(bitvec &val, const IR::Equ *eq);
188 void do_neq(bitvec &val, const IR::Neq *neq);
189 const IR::Node *preorder(IR::LAnd *expr) override;
190 const IR::Node *preorder(IR::P4Control *control) override;
191};
192
199 public:
200 SimplifyNestedIf(ReferenceMap *refMap, TypeMap *typeMap, TypeChecking *typeChecking = nullptr) {
201 std::set<cstring> valid_fields;
202 valid_fields = {"digest_type"_cs, "resubmit_type"_cs, "mirror_type"_cs};
203 auto policy = new UniqueAndValidDest(refMap, typeMap, &valid_fields);
204 auto skip = new ProcessDeparser();
205 if (!typeChecking) typeChecking = new TypeChecking(refMap, typeMap);
206 passes.push_back(typeChecking);
207 passes.push_back(new DoSimplifyNestedIf(skip));
208 passes.push_back(new StrengthReduction(typeMap, typeChecking));
209 passes.push_back(new SimplifyControlFlow(typeMap, typeChecking));
210 passes.push_back(new DoSimplifyComplexCondition(policy, skip));
211 passes.push_back(new BFN::TypeChecking(refMap, typeMap, true));
212 setName("SimplifyNestedIf");
213 }
214};
215
216} // namespace P4
217
218#endif /* _BACKENDS_TOFINO_BF_P4C_MIDEND_SIMPLIFY_NESTED_IF_H_ */
Definition node.h:94
Definition ir/pass_manager.h:40
Class used to encode maps from paths to declarations.
Definition referenceMap.h:66
Definition simplify.h:70
Definition strengthReduction.h:121
Definition visitor.h:424
Definition typeChecker.h:55
Definition typeMap.h:41
Definition bitvec.h:120
Definition ordered_map.h:32
virtual bool convert(const IR::P4Control *control) const =0
bool convert(const IR::P4Control *control) const override
Definition simplify_nested_if.h:64
Pass that tries to simplify the conditions to a simple comparison of constants.
Definition simplify_nested_if.h:172
Definition simplify_nested_if.h:72
Definition simplify_nested_if.h:61
Definition simplify_nested_if.h:103
Top level PassManager that governs simplification of nested if statements in the deparser control blo...
Definition simplify_nested_if.h:198
Definition simplify_nested_if.h:48
Definition simplify_nested_if.h:113
const IR::Parameter * getContainingParameter(const LinearPath &path, P4::ReferenceMap *refMap)
Definition midend/type_categories.cpp:131
bool isIntrinsicMetadataType(const IR::Type *type)
Definition midend/type_categories.cpp:29
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:51
Definition path_linearizer.h:75