Halide  20.0.0
Halide compiler and libraries
IREquality.h
Go to the documentation of this file.
1 #ifndef HALIDE_IR_EQUALITY_H
2 #define HALIDE_IR_EQUALITY_H
3 
4 /** \file
5  * Methods to test Exprs and Stmts for equality of value.
6  *
7  * These methods traverse the entire IR tree. For equality of reference, use
8  * Expr::same_as. If you're comparing non-CSE'd Exprs, use graph_equal or
9  * graph_less_than, which is safe for nasty graphs of IR nodes.
10  */
11 
12 #include "Expr.h"
13 
14 namespace Halide {
15 namespace Internal {
16 
17 // We want to inline a few quick checks into the caller. These are the actual
18 // implementations that get called after those quick checks.
19 bool equal_impl(const IRNode &a, const IRNode &b);
20 bool graph_equal_impl(const IRNode &a, const IRNode &b);
21 bool less_than_impl(const IRNode &a, const IRNode &b);
22 bool graph_less_than_impl(const IRNode &a, const IRNode &b);
23 
24 /** Compare an Expr to an int literal. This is a somewhat common use of equal in
25  * tests. Making this separate avoids constructing an Expr out of the int
26  * literal just to check if it's equal to a. */
28 bool equal(const Expr &a, int b) {
29  if (const IntImm *i = a.as<IntImm>()) {
30  return (a.type() == Int(32) && i->value == b);
31  } else {
32  return false;
33  }
34 }
35 
36 /** Check if two defined Stmts or Exprs are equal. */
38 bool equal(const IRNode &a, const IRNode &b) {
39  if (&a == &b) {
40  return true;
41  } else if (a.node_type != b.node_type) {
42  return false;
43  } else {
44  return equal_impl(a, b);
45  }
46 }
47 
48 /** Check if two possible-undefined Stmts or Exprs are equal. */
50 bool equal(const IRHandle &a, const IRHandle &b) {
51  if (!a.defined()) {
52  return !b.defined();
53  } else if (!b.defined()) {
54  return false;
55  } else {
56  return equal(*(a.get()), *(b.get()));
57  }
58 }
59 
60 /** Check if two defined Stmts or Exprs are equal. Safe to call on Exprs that
61  * haven't been passed to common_subexpression_elimination. */
63 bool graph_equal(const IRNode &a, const IRNode &b) {
64  if (&a == &b) {
65  return true;
66  } else if (a.node_type != b.node_type) {
67  return false;
68  } else {
69  return equal_impl(a, b);
70  }
71 }
72 
73 /** Check if two possibly-undefined Stmts or Exprs are equal. Safe to call on
74  * Exprs that haven't been passed to common_subexpression_elimination. */
76 bool graph_equal(const IRHandle &a, const IRHandle &b) {
77  if (!a.defined()) {
78  return !b.defined();
79  } else if (!b.defined()) {
80  return false;
81  } else {
82  return equal(*(a.get()), *(b.get()));
83  }
84 }
85 
86 /** Check if two defined Stmts or Exprs are in a lexicographic order. For use in
87  * map keys. */
89 bool less_than(const IRNode &a, const IRNode &b) {
90  if (&a == &b) {
91  return false;
92  } else if (a.node_type < b.node_type) {
93  return true;
94  } else {
95  return less_than_impl(a, b);
96  }
97 }
98 
99 /** Check if two possibly-undefined Stmts or Exprs are in a lexicographic
100  * order. For use in map keys. */
102 bool less_than(const IRHandle &a, const IRHandle &b) {
103  if (a.get() == b.get()) {
104  return false;
105  } else if (!a.defined()) {
106  return true;
107  } else if (!b.defined()) {
108  return false;
109  } else {
110  return less_than(*(a.get()), *(b.get()));
111  }
112 }
113 
114 /** Check if two defined Stmts or Exprs are in a lexicographic order. For use in
115  * map keys. Safe to use on Exprs that haven't been passed to
116  * common_subexpression_elimination. */
118 bool graph_less_than(const IRNode &a, const IRNode &b) {
119  if (&a == &b) {
120  return false;
121  } else if (a.node_type < b.node_type) {
122  return true;
123  } else {
124  return graph_less_than_impl(a, b);
125  }
126 }
127 
128 /** Check if two possibly-undefined Stmts or Exprs are in a lexicographic
129  * order. For use in map keys. Safe to use on Exprs that haven't been passed to
130  * common_subexpression_elimination. */
132 bool graph_less_than(const IRHandle &a, const IRHandle &b) {
133  if (a.get() == b.get()) {
134  return false;
135  } else if (!a.defined()) {
136  return true;
137  } else if (!b.defined()) {
138  return false;
139  } else {
140  return graph_less_than(*(a.get()), *(b.get()));
141  }
142 }
143 
144 /** A compare struct built around less_than, for use as the comparison
145  * object in a std::map or std::set. */
147  bool operator()(const IRHandle &a, const IRHandle &b) const {
148  return less_than(a, b);
149  }
150 };
151 
152 /** A compare struct built around graph_less_than, for use as the comparison
153  * object in a std::map or std::set. */
155  bool operator()(const IRHandle &a, const IRHandle &b) const {
156  return graph_less_than(a, b);
157  }
158 };
159 
161 
162 } // namespace Internal
163 } // namespace Halide
164 
165 #endif
Base classes for Halide expressions (Halide::Expr) and statements (Halide::Internal::Stmt)
#define HALIDE_ALWAYS_INLINE
Definition: HalideRuntime.h:49
bool equal(const RDom &bounds0, const RDom &bounds1)
Return true if bounds0 and bounds1 represent the same bounds.
HALIDE_ALWAYS_INLINE bool graph_less_than(const IRNode &a, const IRNode &b)
Check if two defined Stmts or Exprs are in a lexicographic order.
Definition: IREquality.h:118
bool graph_less_than_impl(const IRNode &a, const IRNode &b)
bool equal_impl(const IRNode &a, const IRNode &b)
bool less_than_impl(const IRNode &a, const IRNode &b)
bool graph_equal_impl(const IRNode &a, const IRNode &b)
HALIDE_ALWAYS_INLINE bool less_than(const IRNode &a, const IRNode &b)
Check if two defined Stmts or Exprs are in a lexicographic order.
Definition: IREquality.h:89
HALIDE_ALWAYS_INLINE bool graph_equal(const IRNode &a, const IRNode &b)
Check if two defined Stmts or Exprs are equal.
Definition: IREquality.h:63
void ir_equality_test()
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
Type Int(int bits, int lanes=1)
Constructing a signed integer type.
Definition: Type.h:541
A fragment of Halide syntax.
Definition: Expr.h:258
HALIDE_ALWAYS_INLINE Type type() const
Get the type of this expression node.
Definition: Expr.h:327
A compare struct built around less_than, for use as the comparison object in a std::map or std::set.
Definition: IREquality.h:146
bool operator()(const IRHandle &a, const IRHandle &b) const
Definition: IREquality.h:147
A compare struct built around graph_less_than, for use as the comparison object in a std::map or std:...
Definition: IREquality.h:154
bool operator()(const IRHandle &a, const IRHandle &b) const
Definition: IREquality.h:155
IR nodes are passed around opaque handles to them.
Definition: Expr.h:180
const T * as() const
Downcast this ir node to its actual type (e.g.
Definition: Expr.h:205
The abstract base classes for a node in the Halide IR.
Definition: Expr.h:84
IRNodeType node_type
Each IR node subclass has a unique identifier.
Definition: Expr.h:113
Integer constants.
Definition: Expr.h:218
HALIDE_ALWAYS_INLINE bool defined() const
Definition: IntrusivePtr.h:164
T * get() const
Access the raw pointer in a variety of ways.
Definition: IntrusivePtr.h:102