Halide
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 
12 namespace Halide {
13 namespace Internal {
14 
15 template<typename T = void>
16 class ExprUsesVars : public IRGraphVisitor {
18 
19  const Scope<T> &vars;
20  Scope<Expr> scope;
21 
22  void include(const Expr &e) override {
23  if (result) return;
25  }
26 
27  void include(const Stmt &s) override {
28  if (result) return;
30  }
31 
32  void visit_name(const std::string &name) {
33  if (vars.contains(name)) {
34  result = true;
35  } else if (scope.contains(name)) {
36  include(scope.get(name));
37  }
38  }
39 
40  void visit(const Variable *op) override {
41  visit_name(op->name);
42  }
43 
44  void visit(const Load *op) override {
45  visit_name(op->name);
47  }
48 
49  void visit(const Store *op) override {
50  visit_name(op->name);
52  }
53 
54  void visit(const Call *op) override {
55  visit_name(op->name);
57  }
58 
59  void visit(const Provide *op) override {
60  visit_name(op->name);
62  }
63 
64  void visit(const LetStmt *op) override {
65  visit_name(op->name);
67  }
68 
69  void visit(const Let *op) override {
70  visit_name(op->name);
72  }
73 
74  void visit(const Realize *op) override {
75  visit_name(op->name);
77  }
78 
79  void visit(const Allocate *op) override {
80  visit_name(op->name);
82  }
83 
84 public:
85  ExprUsesVars(const Scope<T> &v, const Scope<Expr> *s = nullptr)
86  : vars(v), result(false) {
87  scope.set_containing_scope(s);
88  }
89  bool result;
90 };
91 
92 /** Test if a statement or expression references or defines any of the
93  * variables in a scope, additionally considering variables bound to
94  * Expr's in the scope provided in the final argument.
95  */
96 template<typename StmtOrExpr, typename T>
97 inline bool stmt_or_expr_uses_vars(const StmtOrExpr &e, const Scope<T> &v,
99  ExprUsesVars<T> uses(v, &s);
100  e.accept(&uses);
101  return uses.result;
102 }
103 
104 /** Test if a statement or expression references or defines the given
105  * variable, additionally considering variables bound to Expr's in the
106  * scope provided in the final argument.
107  */
108 template<typename StmtOrExpr>
109 inline bool stmt_or_expr_uses_var(const StmtOrExpr &e, const std::string &v,
110  const Scope<Expr> &s = Scope<Expr>::empty_scope()) {
111  Scope<> vars;
112  vars.push(v);
113  return stmt_or_expr_uses_vars<StmtOrExpr, void>(e, vars, s);
114 }
115 
116 /** Test if an expression references or defines the given variable,
117  * additionally considering variables bound to Expr's in the scope
118  * provided in the final argument.
119  */
120 inline bool expr_uses_var(const Expr &e, const std::string &v,
121  const Scope<Expr> &s = Scope<Expr>::empty_scope()) {
122  return stmt_or_expr_uses_var(e, v, s);
123 }
124 
125 /** Test if a statement references or defines the given variable,
126  * additionally considering variables bound to Expr's in the scope
127  * provided in the final argument.
128  */
129 inline bool stmt_uses_var(const Stmt &stmt, const std::string &v,
130  const Scope<Expr> &s = Scope<Expr>::empty_scope()) {
131  return stmt_or_expr_uses_var(stmt, v, s);
132 }
133 
134 /** Test if an expression references or defines any of the variables
135  * in a scope, additionally considering variables bound to Expr's in
136  * the scope provided in the final argument.
137  */
138 template<typename T>
139 inline bool expr_uses_vars(const Expr &e, const Scope<T> &v,
140  const Scope<Expr> &s = Scope<Expr>::empty_scope()) {
141  return stmt_or_expr_uses_vars(e, v, s);
142 }
143 
144 /** Test if a statement references or defines any of the variables in
145  * a scope, additionally considering variables bound to Expr's in the
146  * scope provided in the final argument.
147  */
148 template<typename T>
149 inline bool stmt_uses_vars(const Stmt &stmt, const Scope<T> &v,
150  const Scope<Expr> &s = Scope<Expr>::empty_scope()) {
151  return stmt_or_expr_uses_vars(stmt, v, s);
152 }
153 
154 } // namespace Internal
155 } // namespace Halide
156 
157 #endif
Halide::Internal::Allocate
Allocate a scratch area called with the given name, type, and size.
Definition: IR.h:352
Scope.h
Halide::Internal::ExprUsesVars
Definition: ExprUsesVar.h:16
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:149
Halide::Internal::LetStmt::name
std::string name
Definition: IR.h:265
Halide::Internal::Scope::contains
bool contains(const std::string &name) const
Tests if a name is in scope.
Definition: Scope.h:154
Halide::Internal::ExprUsesVars::result
bool result
Definition: ExprUsesVar.h:89
Halide::Internal::LetStmt
The statement form of a let node.
Definition: IR.h:264
Halide::Internal::Scope::get
T2 get(const std::string &name) const
Retrieve the value referred to by a name.
Definition: Scope.h:128
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: ModulusRemainder.h:17
Halide::Internal::Scope::set_containing_scope
void set_containing_scope(const Scope< T > *s)
Set the parent scope.
Definition: Scope.h:113
Halide::Internal::Let::name
std::string name
Definition: IR.h:254
IR.h
Halide::Internal::Stmt
A reference-counted handle to a statement node.
Definition: Expr.h:409
Halide::Internal::Load
Load a value from a named symbol if predicate is true.
Definition: IR.h:199
Halide::Internal::Realize
Allocate a multi-dimensional buffer of the given type and size.
Definition: IR.h:402
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AddAtomicMutex.h:21
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:129
Halide::Internal::Provide
This defines the value of a function at a multi-dimensional location.
Definition: IR.h:336
Halide::Internal::Realize::name
std::string name
Definition: IR.h:403
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
Halide::Internal::Let
A let expression, like you might find in a functional language.
Definition: IR.h:253
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...
IRVisitor.h
Halide::Internal::Store
Store a 'value' to the buffer called 'name' at a given 'index' if 'predicate' is true.
Definition: IR.h:315
Halide::Internal::Provide::name
std::string name
Definition: IR.h:337
Halide::Internal::Scope::push
void push(const std::string &name, T2 &&value)
Add a new (name, value) pair to the current scope.
Definition: Scope.h:181
Halide::Internal::Variable
A named variable.
Definition: IR.h:651
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:139
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:120
Halide::Internal::Call::name
std::string name
Definition: IR.h:465
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:109
Halide::Internal::Store::name
std::string name
Definition: IR.h:316
Halide::Internal::Call
A function call.
Definition: IR.h:464
Halide::Output::stmt
@ stmt
Halide::Expr
A fragment of Halide syntax.
Definition: Expr.h:256
Halide::Internal::IRGraphVisitor
A base class for algorithms that walk recursively over the IR without visiting the same node twice.
Definition: IRVisitor.h:85
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::Variable::name
std::string name
Definition: IR.h:652
Halide::Internal::Allocate::name
std::string name
Definition: IR.h:353
Halide::Internal::Load::name
std::string name
Definition: IR.h:200
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:97
Halide::Internal::ExprUsesVars::ExprUsesVars
ExprUsesVars(const Scope< T > &v, const Scope< Expr > *s=nullptr)
Definition: ExprUsesVar.h:85