14#include <mlir/Support/LogicalResult.h>
98 friend std::strong_ordering
102 return std::is_eq(lhs <=> rhs);
106 llvm::DynamicAPInt
getLHS()
const {
return a; }
107 llvm::DynamicAPInt
getRHS()
const {
return b; }
111 llvm::DynamicAPInt
width()
const;
118 void print(llvm::raw_ostream &os)
const { os <<
"Unreduced:[ " << a <<
", " << b <<
" ]"; }
126 llvm::DynamicAPInt a, b;
203 static constexpr std::array<std::string_view, 7>
TypeNames = {
"TypeA",
"TypeB",
"TypeC",
204 "TypeF",
"Empty",
"Degenerate",
256 template <std::pair<Type, Type>... Pairs>
258 return ((a.ty == std::get<0>(Pairs) && b.ty == std::get<1>(Pairs)) || ...);
322 template <
Type... Types>
bool is()
const {
return ((ty == Types) || ...); }
330 llvm::DynamicAPInt
width()
const;
332 llvm::DynamicAPInt
lhs()
const {
return a; }
333 llvm::DynamicAPInt
rhs()
const {
return b; }
338 return std::hash<const Field *> {}(&i.field.get()) ^ std::hash<Type> {}(i.ty) ^
339 llvm::hash_value(i.a) ^ llvm::hash_value(i.b);
343 void print(llvm::raw_ostream &os)
const;
351 Interval(Type t,
const Field &f) : field(f), ty(t), a(f.zero()), b(f.zero()) {}
352 Interval(
Type t,
const Field &f,
const llvm::DynamicAPInt &
lhs,
const llvm::DynamicAPInt &
rhs)
353 : field(f), ty(t), a(f.reduce(
lhs)), b(f.reduce(
rhs)) {}
355 std::reference_wrapper<const Field> field;
357 llvm::DynamicAPInt a, b;
Information about the prime finite field used for the interval analysis.
llvm::DynamicAPInt zero() const
Returns 0 at the bitwidth of the field.
llvm::DynamicAPInt one() const
Returns 1 at the bitwidth of the field.
Intervals over a finite field.
static Interval True(const Field &f)
llvm::DynamicAPInt rhs() const
static constexpr std::array< std::string_view, 7 > TypeNames
Interval intersect(const Interval &rhs) const
Intersect.
friend Interval boolOr(const Interval &lhs, const Interval &rhs)
static std::string_view TypeName(Type t)
friend Interval operator<<(const Interval &lhs, const Interval &rhs)
void print(llvm::raw_ostream &os) const
UnreducedInterval toUnreduced() const
Convert to an UnreducedInterval.
static Interval Boolean(const Field &f)
friend Interval operator^(const Interval &lhs, const Interval &rhs)
Perform a bitwise XOR between the two intervals.
UnreducedInterval firstUnreduced() const
Get the first side of the interval for TypeF intervals, otherwise just get the full interval as an Un...
static Interval Entire(const Field &f)
bool isDegenerate() const
const Field & getField() const
UnreducedInterval secondUnreduced() const
Get the second side of the interval for TypeA, TypeB, and TypeC intervals.
static Interval TypeF(const Field &f, const llvm::DynamicAPInt &a, const llvm::DynamicAPInt &b)
friend Interval boolAnd(const Interval &lhs, const Interval &rhs)
bool isBoolEither() const
friend llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const Interval &i)
bool operator==(const Interval &rhs) const
friend Interval operator|(const Interval &lhs, const Interval &rhs)
Perform a bitwise OR between the two intervals.
static Interval False(const Field &f)
friend Interval operator*(const Interval &lhs, const Interval &rhs)
static Interval Empty(const Field &f)
Interval operator~() const
static Interval TypeA(const Field &f, const llvm::DynamicAPInt &a, const llvm::DynamicAPInt &b)
llvm::DynamicAPInt lhs() const
static bool areOneOf(const Interval &a, const Interval &b)
friend Interval operator>>(const Interval &lhs, const Interval &rhs)
Interval()
To satisfy the dataflow::ScalarLatticeValue requirements, this class must be default initializable.
static Interval Degenerate(const Field &f, const llvm::DynamicAPInt &val)
llvm::DynamicAPInt width() const
friend Interval operator+(const Interval &lhs, const Interval &rhs)
friend Interval boolXor(const Interval &lhs, const Interval &rhs)
Interval difference(const Interval &other) const
Computes and returns this - (this & other) if the operation produces a single interval.
friend Interval operator%(const Interval &lhs, const Interval &rhs)
static Interval TypeC(const Field &f, const llvm::DynamicAPInt &a, const llvm::DynamicAPInt &b)
Interval operator-() const
static Interval TypeB(const Field &f, const llvm::DynamicAPInt &a, const llvm::DynamicAPInt &b)
Interval join(const Interval &rhs) const
Union.
friend Interval boolNot(const Interval &iv)
friend Interval operator&(const Interval &lhs, const Interval &rhs)
An inclusive interval [a, b] where a and b are arbitrary integers not necessarily bound to a given fi...
UnreducedInterval operator-() const
friend UnreducedInterval operator+(const UnreducedInterval &lhs, const UnreducedInterval &rhs)
UnreducedInterval intersect(const UnreducedInterval &rhs) const
Compute and return the intersection of this interval and the given RHS.
UnreducedInterval(const llvm::DynamicAPInt &x, const llvm::DynamicAPInt &y)
UnreducedInterval(int64_t x, int64_t y)
This constructor is primarily for convenience for unit tests.
bool isEmpty() const
Returns true iff width() is zero.
UnreducedInterval computeLTPart(const UnreducedInterval &rhs) const
Return the part of the interval that is guaranteed to be less than the rhs's max value.
llvm::DynamicAPInt getRHS() const
UnreducedInterval computeGEPart(const UnreducedInterval &rhs) const
Return the part of the interval that is greater than or equal to the rhs's lower bound.
friend std::strong_ordering operator<=>(const UnreducedInterval &lhs, const UnreducedInterval &rhs)
llvm::DynamicAPInt getLHS() const
bool overlaps(const UnreducedInterval &rhs) const
llvm::DynamicAPInt width() const
Compute the width of this interval within a given field f.
friend llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const UnreducedInterval &ui)
friend bool operator==(const UnreducedInterval &lhs, const UnreducedInterval &rhs)
UnreducedInterval doUnion(const UnreducedInterval &rhs) const
Compute and return the union of this interval and the given RHS.
void print(llvm::raw_ostream &os) const
UnreducedInterval computeGTPart(const UnreducedInterval &rhs) const
Return the part of the interval that is greater than the rhs's lower bound.
Interval reduce(const Field &field) const
Reduce the interval to an interval in the given field.
UnreducedInterval computeLEPart(const UnreducedInterval &rhs) const
Return the part of the interval that is less than or equal to the rhs's upper bound.
friend UnreducedInterval operator*(const UnreducedInterval &lhs, const UnreducedInterval &rhs)
FailureOr< Interval > signedIntDiv(const Interval &lhs, const Interval &rhs)
Computes signed integer division with possibly non-Degenerate divisors.
FailureOr< Interval > unsignedIntDiv(const Interval &lhs, const Interval &rhs)
Computes unsigned integer division with possibly non-Degenerate divisors.
FailureOr< Interval > feltDiv(const Interval &lhs, const Interval &rhs)
Computes finite-field division by multiplying the dividend by the multiplicative inverse of the divis...
unsigned operator()(const Interval &i) const