Halide
ModulusRemainder.h
Go to the documentation of this file.
1 #ifndef HALIDE_MODULUS_REMAINDER_H
2 #define HALIDE_MODULUS_REMAINDER_H
3
4 /** \file
5  * Routines for statically determining what expressions are divisible by.
6  */
7
8 #include <stdint.h>
9
10 namespace Halide {
11
12 struct Expr;
13
14 namespace Internal {
15
16 template<typename T>
17 class Scope;
18
19 /** The result of modulus_remainder analysis. These represent strided
20  * subsets of the integers. A ModulusRemainder object m represents all
21  * integers x such that there exists y such that x == m.modulus * y +
22  * m.remainder. Note that under this definition a set containing a
23  * single integer (a constant) is represented using a modulus of
24  * zero. These sets can be combined with several mathematical
25  * operators in the obvious way. E.g. m1 + m2 contains (at least) all
26  * integers x1 + x2 such that x1 belongs to m1 and x2 belongs to
27  * m2. These combinations are conservative. If some internal math
28  * would overflow, it defaults to all of the integers (modulus == 1,
29  * remainder == 0). */
30
33  : modulus(1), remainder(0) {
34  }
36  : modulus(m), remainder(r) {
37  }
38
40
41  // Take a conservatively-large union of two sets. Contains all
42  // elements from both sets, and maybe some more stuff.
43  static ModulusRemainder unify(const ModulusRemainder &a, const ModulusRemainder &b);
44
45  // Take a conservatively-large intersection. Everything in the
46  // result is in at least one of the two sets, but not always both.
48
49  bool operator==(const ModulusRemainder &other) const {
50  return (modulus == other.modulus) && (remainder == other.remainder);
51  }
52 };
53
54 ModulusRemainder operator+(const ModulusRemainder &a, const ModulusRemainder &b);
55 ModulusRemainder operator-(const ModulusRemainder &a, const ModulusRemainder &b);
56 ModulusRemainder operator*(const ModulusRemainder &a, const ModulusRemainder &b);
57 ModulusRemainder operator/(const ModulusRemainder &a, const ModulusRemainder &b);
58 ModulusRemainder operator%(const ModulusRemainder &a, const ModulusRemainder &b);
59
60 ModulusRemainder operator+(const ModulusRemainder &a, int64_t b);
61 ModulusRemainder operator-(const ModulusRemainder &a, int64_t b);
62 ModulusRemainder operator*(const ModulusRemainder &a, int64_t b);
63 ModulusRemainder operator/(const ModulusRemainder &a, int64_t b);
64 ModulusRemainder operator%(const ModulusRemainder &a, int64_t b);
65
66 /** For things like alignment analysis, often it's helpful to know
67  * if an integer expression is some multiple of a constant plus
68  * some other constant. For example, it is straight-forward to
69  * deduce that ((10*x + 2)*(6*y - 3) - 1) is congruent to five
70  * modulo six.
71  *
72  * We get the most information when the modulus is large. E.g. if
73  * something is congruent to 208 modulo 384, then we also know it's
74  * congruent to 0 mod 8, and we can possibly use it as an index for an
75  * aligned load. If all else fails, we can just say that an integer is
76  * congruent to zero modulo one.
77  */
78 ModulusRemainder modulus_remainder(const Expr &e);
79
80 /** If we have alignment information about external variables, we can
81  * let the analysis know about that using this version of
82  * modulus_remainder: */
83 ModulusRemainder modulus_remainder(const Expr &e, const Scope<ModulusRemainder> &scope);
84
85 /** Reduce an expression modulo some integer. Returns true and assigns
86  * to remainder if an answer could be found. */
87 ///@{
88 bool reduce_expr_modulo(const Expr &e, int64_t modulus, int64_t *remainder);
89 bool reduce_expr_modulo(const Expr &e, int64_t modulus, int64_t *remainder, const Scope<ModulusRemainder> &scope);
90 ///@}
91
93
94 /** The greatest common divisor of two integers */
96
97 /** The least common multiple of two integers */
99
100 } // namespace Internal
101 } // namespace Halide
102
103 #endif
Halide::Internal::operator*
ModulusRemainder operator*(const ModulusRemainder &a, const ModulusRemainder &b)
Halide::Internal::ModulusRemainder::intersect
static ModulusRemainder intersect(const ModulusRemainder &a, const ModulusRemainder &b)
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::ModulusRemainder::operator==
bool operator==(const ModulusRemainder &other) const
Definition: ModulusRemainder.h:49
Halide::Internal::modulus_remainder_test
void modulus_remainder_test()
Halide::Internal::gcd
int64_t gcd(int64_t, int64_t)
The greatest common divisor of two integers.
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
Halide::Internal::ModulusRemainder::ModulusRemainder
ModulusRemainder()
Definition: ModulusRemainder.h:32
Halide::Internal::operator-
ModulusRemainder operator-(const ModulusRemainder &a, const ModulusRemainder &b)
int64_t
signed __INT64_TYPE__ int64_t
Definition: runtime_internal.h:18
Halide::Internal::lcm
int64_t lcm(int64_t, int64_t)
The least common multiple of two integers.
Halide::Internal::ModulusRemainder::modulus
int64_t modulus
Definition: ModulusRemainder.h:39
Halide::Internal::reduce_expr_modulo
bool reduce_expr_modulo(const Expr &e, int64_t modulus, int64_t *remainder)
Reduce an expression modulo some integer.
Halide::Internal::ModulusRemainder::unify
static ModulusRemainder unify(const ModulusRemainder &a, const ModulusRemainder &b)
Halide::Internal::modulus_remainder
ModulusRemainder modulus_remainder(const Expr &e)
For things like alignment analysis, often it's helpful to know if an integer expression is some multi...
Halide::Internal::operator%
ModulusRemainder operator%(const ModulusRemainder &a, const ModulusRemainder &b)
Halide::Expr
A fragment of Halide syntax.
Definition: Expr.h:256
Halide::Internal::ModulusRemainder::remainder
int64_t remainder
Definition: ModulusRemainder.h:39
Halide::Internal::operator/
ModulusRemainder operator/(const ModulusRemainder &a, const ModulusRemainder &b)
Halide::Internal::ModulusRemainder
The result of modulus_remainder analysis.
Definition: ModulusRemainder.h:31
Halide::Internal::operator+
ModulusRemainder operator+(const ModulusRemainder &a, const ModulusRemainder &b)
Halide::Internal::ModulusRemainder::ModulusRemainder
ModulusRemainder(int64_t m, int64_t r)
Definition: ModulusRemainder.h:35