Halide 22.0.0 Halide compiler and libraries

ExprUsesVar.h
Go to the documentation of this file.
1#ifndef HALIDE_EXPR_USES_VAR_H
2#define HALIDE_EXPR_USES_VAR_H
3
4/** \file
5 * Defines a method to determine if an expression depends on some variables.
6 */
7
8#include "IR.h"
9#include "IRVisitor.h"
10#include "Scope.h"
11
12namespace Halide {
13namespace Internal {
14
15template<typename T = void>
16 class ExprUsesVars : public IRGraphVisitor {
17 using IRGraphVisitor::visit;
18
19 const Scope<T> &vars;
20 Scope<Expr> scope;
21
22 void include(const Expr &e) override {
23 if (result) {
24 return;
25 }
26 IRGraphVisitor::include(e);
27 }
28
29 void include(const Stmt &s) override {
30 if (result) {
31 return;
32 }
33 IRGraphVisitor::include(s);
34 }
35
36 void visit_name(const std::string &name) {
37 if (vars.contains(name)) {
38 result = true;
39 } else if (const Expr *e = scope.find(name)) {
40 IRGraphVisitor::include(*e);
41 }
42 }
43
44 void visit(const Variable *op) override {
45 visit_name(op->name);
46 }
47
48 void visit(const Load *op) override {
49 visit_name(op->name);
50 IRGraphVisitor::visit(op);
51 }
52
53 void visit(const Store *op) override {
54 visit_name(op->name);
55 IRGraphVisitor::visit(op);
56 }
57
58 void visit(const Call *op) override {
59 visit_name(op->name);
60 IRGraphVisitor::visit(op);
61 }
62
63 void visit(const Provide *op) override {
64 visit_name(op->name);
65 IRGraphVisitor::visit(op);
66 }
67
68 void visit(const LetStmt *op) override {
69 visit_name(op->name);
70 IRGraphVisitor::visit(op);
71 }
72
73 void visit(const Let *op) override {
74 visit_name(op->name);
75 IRGraphVisitor::visit(op);
76 }
77
78 void visit(const Realize *op) override {
79 visit_name(op->name);
80 IRGraphVisitor::visit(op);
81 }
82
83 void visit(const Allocate *op) override {
84 visit_name(op->name);
85 IRGraphVisitor::visit(op);
86 }
87
88public:
89 ExprUsesVars(const Scope<T> &v, const Scope<Expr> *s = nullptr)
90 : vars(v) {
91 scope.set_containing_scope(s);
92 }
93 bool result = false;
94};
95
96/** Test if a statement or expression references or defines any of the
97 * variables in a scope, additionally considering variables bound to
98 * Expr's in the scope provided in the final argument.
99 */
100template<typename StmtOrExpr, typename T>
101 inline bool stmt_or_expr_uses_vars(const StmtOrExpr &e, const Scope<T> &v,
102 const Scope<Expr> &s = Scope<Expr>::empty_scope()) {
103 ExprUsesVars<T> uses(v, &s);
104 e.accept(&uses);
105 return uses.result;
106}
107
108/** Test if a statement or expression references or defines the given
109 * variable, additionally considering variables bound to Expr's in the
110 * scope provided in the final argument.
111 */
112template<typename StmtOrExpr>
113 inline bool stmt_or_expr_uses_var(const StmtOrExpr &e, const std::string &v,
114 const Scope<Expr> &s = Scope<Expr>::empty_scope()) {
115 Scope<> vars;
116 vars.push(v);
117 return stmt_or_expr_uses_vars<StmtOrExpr, void>(e, vars, s);
118}
119
120/** Test if an expression references or defines the given variable,
121 * additionally considering variables bound to Expr's in the scope
122 * provided in the final argument.
123 */
124 inline bool expr_uses_var(const Expr &e, const std::string &v,
125 const Scope<Expr> &s = Scope<Expr>::empty_scope()) {
126 return stmt_or_expr_uses_var(e, v, s);
127}
128
129/** Test if a statement references or defines the given variable,
130 * additionally considering variables bound to Expr's in the scope
131 * provided in the final argument.
132 */
133 inline bool stmt_uses_var(const Stmt &stmt, const std::string &v,
134 const Scope<Expr> &s = Scope<Expr>::empty_scope()) {
135 return stmt_or_expr_uses_var(stmt, v, s);
136}
137
138/** Test if an expression references or defines any of the variables
139 * in a scope, additionally considering variables bound to Expr's in
140 * the scope provided in the final argument.
141 */
142template<typename T>
143 inline bool expr_uses_vars(const Expr &e, const Scope<T> &v,
144 const Scope<Expr> &s = Scope<Expr>::empty_scope()) {
145 return stmt_or_expr_uses_vars(e, v, s);
146}
147
148/** Test if a statement references or defines any of the variables in
149 * a scope, additionally considering variables bound to Expr's in the
150 * scope provided in the final argument.
151 */
152template<typename T>
153 inline bool stmt_uses_vars(const Stmt &stmt, const Scope<T> &v,
154 const Scope<Expr> &s = Scope<Expr>::empty_scope()) {
155 return stmt_or_expr_uses_vars(stmt, v, s);
156}
157
158} // namespace Internal
159} // namespace Halide
160
161#endif
IR.h
Subtypes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt)
IRVisitor.h
Defines the base class for things that recursively walk over the IR.
Scope.h
Defines the Scope class, which is used for keeping track of names in a scope while traversing IR.
Halide::Internal::ExprUsesVars
Definition: ExprUsesVar.h:16
Halide::Internal::ExprUsesVars::ExprUsesVars
ExprUsesVars(const Scope< T > &v, const Scope< Expr > *s=nullptr)
Definition: ExprUsesVar.h:89
Halide::Internal::ExprUsesVars::result
bool result
Definition: ExprUsesVar.h:93
Halide::Internal::IRGraphVisitor
A base class for algorithms that walk recursively over the IR without visiting the same node twice.
Definition: IRVisitor.h:272
Halide::Internal::IRGraphVisitor::include
virtual void include(const Expr &)
By default these methods add the node to the visited set, and return whether or not it was already th...
Halide::Internal::IRGraphVisitor::visit
void visit(const IntImm *) override
These methods should call 'include' on the children to only visit them if they haven't been visited a...
Halide::Internal::Scope
A common pattern when traversing Halide IR is that you need to keep track of stuff when you find a Le...
Definition: Scope.h:94
Halide::Internal::Scope::find
const T2 * find(const std::string &name) const
Returns a const pointer to an entry if it exists in this scope or any containing scope,...
Definition: Scope.h:159
Halide::Internal::Scope::contains
bool contains(const std::string &name) const
Tests if a name is in scope.
Definition: Scope.h:186
Halide::Internal::Scope::push
PushToken push(const std::string &name, T2 &&value)
Add a new (name, value) pair to the current scope.
Definition: Scope.h:223
Halide::Internal::Scope::set_containing_scope
void set_containing_scope(const Scope< T > *s)
Set the parent scope.
Definition: Scope.h:113
Halide::Internal::stmt_uses_var
bool stmt_uses_var(const Stmt &stmt, const std::string &v, const Scope< Expr > &s=Scope< Expr >::empty_scope())
Test if a statement references or defines the given variable, additionally considering variables boun...
Definition: ExprUsesVar.h:133
Halide::Internal::stmt_or_expr_uses_vars
bool stmt_or_expr_uses_vars(const StmtOrExpr &e, const Scope< T > &v, const Scope< Expr > &s=Scope< Expr >::empty_scope())
Test if a statement or expression references or defines any of the variables in a scope,...
Definition: ExprUsesVar.h:101
Halide::Internal::stmt_uses_vars
bool stmt_uses_vars(const Stmt &stmt, const Scope< T > &v, const Scope< Expr > &s=Scope< Expr >::empty_scope())
Test if a statement references or defines any of the variables in a scope, additionally considering v...
Definition: ExprUsesVar.h:153
Halide::Internal::stmt_or_expr_uses_var
bool stmt_or_expr_uses_var(const StmtOrExpr &e, const std::string &v, const Scope< Expr > &s=Scope< Expr >::empty_scope())
Test if a statement or expression references or defines the given variable, additionally considering ...
Definition: ExprUsesVar.h:113
Halide::Internal::expr_uses_vars
bool expr_uses_vars(const Expr &e, const Scope< T > &v, const Scope< Expr > &s=Scope< Expr >::empty_scope())
Test if an expression references or defines any of the variables in a scope, additionally considering...
Definition: ExprUsesVar.h:143
Halide::Internal::expr_uses_var
bool expr_uses_var(const Expr &e, const std::string &v, const Scope< Expr > &s=Scope< Expr >::empty_scope())
Test if an expression references or defines the given variable, additionally considering variables bo...
Definition: ExprUsesVar.h:124
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AbstractGenerator.h:19
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
Halide::OutputFileType::stmt
@ stmt
Halide::Expr
A fragment of Halide syntax.
Definition: Expr.h:258
Halide::Internal::Allocate
Allocate a scratch area called with the given name, type, and size.
Definition: IR.h:381
Halide::Internal::Allocate::name
std::string name
Definition: IR.h:382
Halide::Internal::Call
A function call.
Definition: IR.h:500
Halide::Internal::Call::name
std::string name
Definition: IR.h:501
Halide::Internal::Let
A let expression, like you might find in a functional language.
Definition: IR.h:281
Halide::Internal::Let::name
std::string name
Definition: IR.h:282
Halide::Internal::LetStmt
The statement form of a let node.
Definition: IR.h:292
Halide::Internal::LetStmt::name
std::string name
Definition: IR.h:293
Halide::Internal::Load
Load a value from a named symbol if predicate is true.
Definition: IR.h:227
Halide::Internal::Load::name
std::string name
Definition: IR.h:228
Halide::Internal::Provide
This defines the value of a function at a multi-dimensional location.
Definition: IR.h:364
Halide::Internal::Provide::name
std::string name
Definition: IR.h:365
Halide::Internal::Realize
Allocate a multi-dimensional buffer of the given type and size.
Definition: IR.h:437
Halide::Internal::Realize::name
std::string name
Definition: IR.h:438
Halide::Internal::Stmt
A reference-counted handle to a statement node.
Definition: Expr.h:427
Halide::Internal::Store
Store a 'value' to the buffer called 'name' at a given 'index' if 'predicate' is true.
Definition: IR.h:343
Halide::Internal::Store::name
std::string name
Definition: IR.h:344
Halide::Internal::Variable
A named variable.
Definition: IR.h:813
Halide::Internal::Variable::name
std::string name
Definition: IR.h:814