14#include <mlir/Support/LogicalResult.h>
37 {lhs.a.getBitWidth(), lhs.b.getBitWidth(), rhs.a.getBitWidth(), rhs.b.getBitWidth()}
112 friend std::strong_ordering
116 return std::is_eq(lhs <=> rhs);
120 llvm::APSInt
getLHS()
const {
return a; }
121 llvm::APSInt
getRHS()
const {
return b; }
125 llvm::APSInt
width()
const;
132 void print(llvm::raw_ostream &os)
const { os <<
"Unreduced:[ " << a <<
", " << b <<
" ]"; }
217 static constexpr std::array<std::string_view, 7>
TypeNames = {
"TypeA",
"TypeB",
"TypeC",
218 "TypeF",
"Empty",
"Degenerate",
270 template <std::pair<Type, Type>... Pairs>
272 return ((a.ty == std::get<0>(Pairs) && b.ty == std::get<1>(Pairs)) || ...);
332 template <
Type... Types>
bool is()
const {
return ((ty == Types) || ...); }
340 llvm::APSInt
width()
const;
342 llvm::APSInt
lhs()
const {
return a; }
343 llvm::APSInt
rhs()
const {
return b; }
348 return std::hash<const Field *> {}(&i.field.get()) ^ std::hash<Type> {}(i.ty) ^
349 llvm::hash_value(i.a) ^ llvm::hash_value(i.b);
353 void print(llvm::raw_ostream &os)
const;
361 Interval(Type t,
const Field &f) : field(f), ty(t), a(f.zero()), b(f.zero()) {}
363 : field(f), ty(t), a(f.reduce(
lhs)), b(f.reduce(
rhs)) {}
365 std::reference_wrapper<const Field> field;
Information about the prime finite field used for the interval analysis.
llvm::APSInt one() const
Returns 1 at the bitwidth of the field.
llvm::APSInt zero() const
Returns 0 at the bitwidth of the field.
Intervals over a finite field.
static Interval True(const Field &f)
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 TypeC(const Field &f, llvm::APSInt a, llvm::APSInt b)
static Interval TypeF(const Field &f, llvm::APSInt a, llvm::APSInt b)
friend Interval boolAnd(const Interval &lhs, const Interval &rhs)
bool isBoolEither() const
static Interval TypeB(const Field &f, llvm::APSInt a, llvm::APSInt b)
friend llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const Interval &i)
bool operator==(const Interval &rhs) const
llvm::APSInt width() 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 bool areOneOf(const Interval &a, const Interval &b)
friend Interval operator>>(const Interval &lhs, const Interval &rhs)
static Interval Degenerate(const Field &f, llvm::APSInt val)
Interval()
To satisfy the dataflow::ScalarLatticeValue requirements, this class must be default initializable.
friend mlir::FailureOr< Interval > operator/(const Interval &lhs, const Interval &rhs)
Returns failure if a division-by-zero is encountered.
static Interval TypeA(const Field &f, llvm::APSInt a, llvm::APSInt b)
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)
Interval operator-() const
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(llvm::APInt x, llvm::APInt y)
bool isEmpty() const
Returns true iff width() is zero.
UnreducedInterval(llvm::APSInt x, llvm::APSInt y)
llvm::APSInt width() const
Compute the width of this interval within a given field f.
UnreducedInterval computeLTPart(const UnreducedInterval &rhs) const
Return the part of the interval that is guaranteed to be less than the rhs's max value.
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)
UnreducedInterval(uint64_t x, uint64_t y)
This constructor is primarily for convenience for unit tests.
bool overlaps(const UnreducedInterval &rhs) const
llvm::APSInt getRHS() const
friend llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const UnreducedInterval &ui)
llvm::APSInt getLHS() const
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
static size_t getMaxBitWidth(const UnreducedInterval &lhs, const UnreducedInterval &rhs)
A utility method to determine the largest bitwidth among arms of two UnreducedIntervals.
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