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) {
24  return;
25  }
27  }
28 
29  void include(const Stmt &s) override {
30  if (result) {
31  return;
32  }
34  }
35 
36  void visit_name(const std::string &name) {
37  if (vars.contains(name)) {
38  result = true;
39  } else if (scope.contains(name)) {
40  include(scope.get(name));
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);
51  }
52 
53  void visit(const Store *op) override {
54  visit_name(op->name);
56  }
57 
58  void visit(const Call *op) override {
59  visit_name(op->name);
61  }
62 
63  void visit(const Provide *op) override {
64  visit_name(op->name);
66  }
67 
68  void visit(const LetStmt *op) override {
69  visit_name(op->name);
71  }
72 
73  void visit(const Let *op) override {
74  visit_name(op->name);
76  }
77 
78  void visit(const Realize *op) override {
79  visit_name(op->name);
81  }
82 
83  void visit(const Allocate *op) override {
84  visit_name(op->name);
86  }
87 
88 public:
89  ExprUsesVars(const Scope<T> &v, const Scope<Expr> *s = nullptr)
90  : vars(v), result(false) {
91  scope.set_containing_scope(s);
92  }
93  bool result;
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  */
100 template<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  */
112 template<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  */
142 template<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  */
152 template<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
Halide::Internal::Allocate
Allocate a scratch area called with the given name, type, and size.
Definition: IR.h:363
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:153
Halide::Internal::LetStmt::name
std::string name
Definition: IR.h:275
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:93
Halide::Internal::LetStmt
The statement form of a let node.
Definition: IR.h:274
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:264
IR.h
Halide::Internal::Stmt
A reference-counted handle to a statement node.
Definition: Expr.h:418
Halide::Internal::Load
Load a value from a named symbol if predicate is true.
Definition: IR.h:209
Halide::Internal::Realize
Allocate a multi-dimensional buffer of the given type and size.
Definition: IR.h:419
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AbstractGenerator.h:19
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::Provide
This defines the value of a function at a multi-dimensional location.
Definition: IR.h:346
Halide::Internal::Realize::name
std::string name
Definition: IR.h:420
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:263
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::OutputFileType::stmt
@ stmt
IRVisitor.h
Halide::Internal::Store
Store a 'value' to the buffer called 'name' at a given 'index' if 'predicate' is true.
Definition: IR.h:325
Halide::Internal::Provide::name
std::string name
Definition: IR.h:347
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:741
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::Internal::Call::name
std::string name
Definition: IR.h:483
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::Store::name
std::string name
Definition: IR.h:326
Halide::Internal::Call
A function call.
Definition: IR.h:482
Halide::Expr
A fragment of Halide syntax.
Definition: Expr.h:257
Halide::Internal::IRGraphVisitor
A base class for algorithms that walk recursively over the IR without visiting the same node twice.
Definition: IRVisitor.h:84
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:742
Halide::Internal::Allocate::name
std::string name
Definition: IR.h:364
Halide::Internal::Load::name
std::string name
Definition: IR.h:210
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::ExprUsesVars::ExprUsesVars
ExprUsesVars(const Scope< T > &v, const Scope< Expr > *s=nullptr)
Definition: ExprUsesVar.h:89