48 const std::set<cstring> *skip;
51 if (control->is<IR::BFN::TnaDeparser>()) {
55 if (control->name == c)
return false;
59 static const IR::Type_Extern *externType(
const IR::Type *type) {
60 if (
auto *spec = type->to<IR::Type_SpecializedCanonical>()) type = spec->baseType;
61 return type->to<IR::Type_Extern>();
65 std::set<cstring> &writes;
66 bool preorder(
const IR::PathExpression *pe) {
67 if (
isWrite()) writes.insert(pe->toString());
70 bool preorder(
const IR::Member *m) {
71 if (
isWrite()) writes.insert(m->toString());
74 bool preorder(
const IR::AssignmentStatement *assign) {
77 if (
auto *mc = assign->right->to<IR::MethodCallExpression>()) {
78 if (
auto *m = mc->method->to<IR::Member>()) {
79 if (
auto *et = externType(m->expr->type)) {
80 if (et->name ==
"Hash" && m->member ==
"get")
return false;
88 explicit FindPathsWritten(std::set<cstring> &w) : writes(w) {}
93 std::set<cstring> &paths;
95 bool preorder(
const IR::PathExpression *pe) {
96 if (paths.count(pe->toString())) rv =
true;
99 bool preorder(
const IR::Member *m) {
100 if (paths.count(m->toString())) rv =
true;
103 bool preorder(
const IR::Node *) {
return !rv; }
104 void postorder(
const IR::MethodCallExpression *mc) {
107 for (
auto *n : em->mayCall()) {
108 if (
auto *fn = n->to<IR::Function>()) {
109 visit(fn->body,
"body");
116 explicit operator bool() {
return rv; }
118 : self(self), paths(p), rv(
false) {
123 class ReferencesExtern :
public Inspector {
125 bool preorder(
const IR::PathExpression *pe) {
126 if (rv)
return false;
127 auto *et = externType(pe->type);
128 if (et && et->name !=
"Hash") {
133 bool preorder(
const IR::Node *) {
return !rv; }
136 explicit operator bool() {
return rv; }
137 explicit ReferencesExtern(
const IR::Node *n) { n->apply(*
this); }
145 bool isRegisterWriteAfterRead(
const IR::BlockStatement *blk,
const IR::StatOrDecl *stmt_decl) {
146 auto *blk_stmt = blk->components.back()->
to<IR::Statement>();
147 if (!blk_stmt)
return false;
149 auto *read_mce = read_rv.first;
150 if (!read_mce)
return false;
152 auto *stmt = stmt_decl->to<IR::Statement>();
153 if (!stmt)
return false;
155 auto *write_mce = write_rv.first;
156 if (!write_mce)
return false;
160 if (!read_inst || !read_inst->object)
return false;
161 auto *read_decl = read_inst->object->to<IR::Declaration_Instance>();
162 if (!read_decl)
return false;
164 auto *read_member = read_mce->method->to<IR::Member>();
165 if (!read_member)
return false;
166 auto *read_extern_type = externType(read_member->expr->type);
167 if (!read_extern_type)
return false;
168 if (read_extern_type->name !=
"Register" || read_member->member !=
"read")
return false;
172 if (!write_inst || !write_inst->object)
return false;
173 auto *write_decl = write_inst->object->to<IR::Declaration_Instance>();
174 if (!write_decl)
return false;
176 auto *write_member = write_mce->method->to<IR::Member>();
177 if (!write_member)
return false;
178 auto *write_extern_type = externType(write_member->expr->type);
179 if (!write_extern_type)
return false;
180 if (write_extern_type->name !=
"Register" || write_member->member !=
"write")
return false;
182 if (read_decl->declid != write_decl->declid)
return false;
188 const IR::StatOrDecl *stmt)
override {
189 if (isRegisterWriteAfterRead(blk, stmt))
return true;
190 std::set<cstring> writes;
191 if (ReferencesExtern(blk) && ReferencesExtern(stmt))
return false;
192 blk->apply(FindPathsWritten(writes));
193 return !DependsOnPaths(*
this, stmt, writes);
199 : refMap(refMap), typeMap(typeMap), skip(skip) {
static MethodInstance * resolve(const IR::MethodCallExpression *mce, const DeclarationLookup *refMap, TypeMap *typeMap, bool useExpressionType=false, const Visitor::Context *ctxt=nullptr, bool incomplete=false)
Definition methodInstance.cpp:27
Definition tofino_write_context.h:24
bool isWrite(bool root_value=false)
Definition ir/tofino_write_context.cpp:23