Halide 19.0.0
Halide compiler and libraries
Loading...
Searching...
No Matches
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 <cstdint>
9
10#include "Util.h"
11
12namespace Halide {
13
14struct Expr;
15
16namespace Internal {
17
18template<typename T>
19class Scope;
20
21/** The result of modulus_remainder analysis. These represent strided
22 * subsets of the integers. A ModulusRemainder object m represents all
23 * integers x such that there exists y such that x == m.modulus * y +
24 * m.remainder. Note that under this definition a set containing a
25 * single integer (a constant) is represented using a modulus of
26 * zero. These sets can be combined with several mathematical
27 * operators in the obvious way. E.g. m1 + m2 contains (at least) all
28 * integers x1 + x2 such that x1 belongs to m1 and x2 belongs to
29 * m2. These combinations are conservative. If some internal math
30 * would overflow, it defaults to all of the integers (modulus == 1,
31 * remainder == 0). */
32
34 ModulusRemainder() = default;
38
40
41 // Take a conservatively-large union of two sets. Contains all
42 // elements from both sets, and maybe some more stuff.
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
59
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 */
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: */
84
85/** Reduce an expression modulo some integer. Returns true and assigns
86 * to remainder if an answer could be found. */
87///@{
88HALIDE_MUST_USE_RESULT bool reduce_expr_modulo(const Expr &e, int64_t modulus, int64_t *remainder);
89HALIDE_MUST_USE_RESULT 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
#define HALIDE_MUST_USE_RESULT
Various utility functions used internally Halide.
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
ConstantInterval operator*(const ConstantInterval &a, const ConstantInterval &b)
ModulusRemainder modulus_remainder(const Expr &e)
For things like alignment analysis, often it's helpful to know if an integer expression is some multi...
int64_t gcd(int64_t, int64_t)
The greatest common divisor of two integers.
ConstantInterval operator%(const ConstantInterval &a, const ConstantInterval &b)
ConstantInterval operator/(const ConstantInterval &a, const ConstantInterval &b)
void modulus_remainder_test()
ConstantInterval operator-(const ConstantInterval &a, const ConstantInterval &b)
ConstantInterval operator+(const ConstantInterval &a, const ConstantInterval &b)
Arithmetic operators on ConstantIntervals.
HALIDE_MUST_USE_RESULT bool reduce_expr_modulo(const Expr &e, int64_t modulus, int64_t *remainder)
Reduce an expression modulo some integer.
int64_t lcm(int64_t, int64_t)
The least common multiple of two integers.
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
signed __INT64_TYPE__ int64_t
A fragment of Halide syntax.
Definition Expr.h:258
The result of modulus_remainder analysis.
static ModulusRemainder unify(const ModulusRemainder &a, const ModulusRemainder &b)
ModulusRemainder(int64_t m, int64_t r)
bool operator==(const ModulusRemainder &other) const
static ModulusRemainder intersect(const ModulusRemainder &a, const ModulusRemainder &b)