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)) || ...);
318 template <
Type... Types>
bool is()
const {
return ((ty == Types) || ...); }
326 llvm::DynamicAPInt
width()
const;
328 llvm::DynamicAPInt
lhs()
const {
return a; }
329 llvm::DynamicAPInt
rhs()
const {
return b; }
334 return std::hash<const Field *> {}(&i.field.get()) ^ std::hash<Type> {}(i.ty) ^
335 llvm::hash_value(i.a) ^ llvm::hash_value(i.b);
339 void print(llvm::raw_ostream &os)
const;
347 Interval(Type t,
const Field &f) : field(f), ty(t), a(f.zero()), b(f.zero()) {}
348 Interval(
Type t,
const Field &f,
const llvm::DynamicAPInt &
lhs,
const llvm::DynamicAPInt &
rhs)
349 : field(f), ty(t), a(f.reduce(
lhs)), b(f.reduce(
rhs)) {}
351 std::reference_wrapper<const Field> field;
353 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)
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
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)
friend mlir::FailureOr< Interval > operator/(const Interval &lhs, const Interval &rhs)
Returns failure if a division-by-zero is encountered.
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)
unsigned operator()(const Interval &i) const