-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
720 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#ifndef HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_H_ | ||
#define HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_H_ | ||
|
||
#include "include/Dialect/Poly/IR/PolyDialect.h" | ||
#include "include/Dialect/Poly/IR/Polynomial.h" | ||
|
||
#define GET_ATTRDEF_CLASSES | ||
#include "include/Dialect/Poly/IR/PolyAttributes.h.inc" | ||
|
||
#endif // HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#ifndef HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_TD_ | ||
#define HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_TD_ | ||
|
||
include "PolyDialect.td" | ||
|
||
include "mlir/IR/DialectBase.td" | ||
include "mlir/IR/AttrTypeBase.td" | ||
|
||
class Poly_Attr<string name, string attrMnemonic, list<Trait> traits = []> | ||
: AttrDef<Poly_Dialect, name, traits> { | ||
let mnemonic = attrMnemonic; | ||
} | ||
|
||
class Poly_Attr_With_Custom_Format<string name, list<Trait> traits = []> | ||
: AttrDef<Poly_Dialect, name, traits> { | ||
let mnemonic = ?; | ||
} | ||
|
||
def Polynomial_Attr : Poly_Attr<"Polynomial", "polynomial"> { | ||
let summary = "An attribute containing a polynomial."; | ||
let description = [{ | ||
#poly = #poly.poly<x^1024 + 1> | ||
}]; | ||
|
||
let parameters = (ins "Polynomial":$value); | ||
|
||
let builders = [ | ||
AttrBuilderWithInferredContext<(ins "Polynomial":$value), [{ | ||
return $_get(value.getContext(), value); | ||
}]> | ||
]; | ||
let extraClassDeclaration = [{ | ||
using ValueType = Polynomial; | ||
Polynomial getPolynomial() const { return getValue(); } | ||
}]; | ||
|
||
let skipDefaultBuilders = 1; | ||
let hasCustomAssemblyFormat = 1; | ||
} | ||
|
||
#endif // HEIR_INCLUDE_DIALECT_POLY_IR_POLYATTRIBUTES_TD_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
#ifndef HEIR_INCLUDE_DIALECT_POLY_IR_POLYNOMIAL_H_ | ||
#define HEIR_INCLUDE_DIALECT_POLY_IR_POLYNOMIAL_H_ | ||
|
||
#include "llvm/ADT/APInt.h" | ||
#include "llvm/ADT/DenseMapInfo.h" | ||
#include "llvm/ADT/Hashing.h" | ||
#include "mlir/Support/LLVM.h" | ||
|
||
namespace mlir { | ||
|
||
class MLIRContext; | ||
|
||
namespace heir { | ||
namespace poly { | ||
|
||
constexpr unsigned APINT_BIT_WIDTH = 64; | ||
|
||
namespace detail { | ||
struct PolynomialStorage; | ||
} // namespace detail | ||
|
||
class Monomial { | ||
public: | ||
Monomial(int64_t coeff, uint64_t expo) | ||
: coefficient(APINT_BIT_WIDTH, coeff), exponent(APINT_BIT_WIDTH, expo) {} | ||
|
||
Monomial(APInt coeff, APInt expo) : coefficient(coeff), exponent(expo) {} | ||
|
||
Monomial() : coefficient(APINT_BIT_WIDTH, 0), exponent(APINT_BIT_WIDTH, 0) {} | ||
|
||
bool operator==(Monomial other) const { | ||
return other.coefficient == coefficient && other.exponent == exponent; | ||
} | ||
bool operator!=(Monomial other) const { | ||
return other.coefficient != coefficient || other.exponent != exponent; | ||
} | ||
|
||
/// Monomials are ordered by exponent. | ||
bool operator<(const Monomial &other) const { | ||
return (exponent.ule(other.exponent)); | ||
} | ||
|
||
// Prints polynomial to 'os'. | ||
void print(raw_ostream &os) const; | ||
|
||
friend ::llvm::hash_code hash_value(Monomial arg); | ||
|
||
public: | ||
APInt coefficient; | ||
|
||
// Always unsigned | ||
APInt exponent; | ||
}; | ||
|
||
/// A single-variable polynomial with integer coefficients. Polynomials are | ||
/// immutable and uniqued. | ||
/// | ||
/// Eg: x^1024 + x + 1 | ||
/// | ||
/// The symbols used as the polynomial's indeterminate don't matter, so long as | ||
/// it is used consistently throughout the polynomial. | ||
class Polynomial { | ||
public: | ||
using ImplType = detail::PolynomialStorage; | ||
|
||
constexpr Polynomial() = default; | ||
explicit Polynomial(ImplType *terms) : terms(terms) {} | ||
|
||
static Polynomial fromMonomials(ArrayRef<Monomial> monomials, | ||
MLIRContext *context); | ||
/// Returns a polynomial with coefficients given by `coeffs` | ||
static Polynomial fromCoefficients(ArrayRef<int64_t> coeffs, | ||
MLIRContext *context); | ||
|
||
/// Builds a monomial of the given degree. | ||
static Polynomial monomialOfDegree(uint64_t degree, MLIRContext *context); | ||
|
||
MLIRContext *getContext() const; | ||
|
||
explicit operator bool() const { return terms != nullptr; } | ||
bool operator==(Polynomial other) const { return other.terms == terms; } | ||
bool operator!=(Polynomial other) const { return !(other.terms == terms); } | ||
|
||
Polynomial operator+(Polynomial other) const; | ||
|
||
// Prints polynomial to 'os'. | ||
void print(raw_ostream &os) const; | ||
void dump() const; | ||
|
||
ArrayRef<Monomial> getTerms() const; | ||
|
||
unsigned getDegree() const; | ||
|
||
friend ::llvm::hash_code hash_value(Polynomial arg); | ||
|
||
private: | ||
ImplType *terms{nullptr}; | ||
}; | ||
|
||
// Make Polynomial hashable. | ||
inline ::llvm::hash_code hash_value(Polynomial arg) { | ||
return ::llvm::hash_value(arg.terms); | ||
} | ||
|
||
inline ::llvm::hash_code hash_value(Monomial arg) { | ||
return ::llvm::hash_value(arg.coefficient) ^ ::llvm::hash_value(arg.exponent); | ||
} | ||
|
||
inline raw_ostream &operator<<(raw_ostream &os, Polynomial polynomial) { | ||
polynomial.print(os); | ||
return os; | ||
} | ||
|
||
} // namespace poly | ||
} // namespace heir | ||
} // namespace mlir | ||
|
||
namespace llvm { | ||
|
||
// Polynomials hash just like pointers | ||
template <> | ||
struct DenseMapInfo<mlir::heir::poly::Polynomial> { | ||
static mlir::heir::poly::Polynomial getEmptyKey() { | ||
auto *pointer = llvm::DenseMapInfo<void *>::getEmptyKey(); | ||
return mlir::heir::poly::Polynomial( | ||
static_cast<mlir::heir::poly::Polynomial::ImplType *>(pointer)); | ||
} | ||
static mlir::heir::poly::Polynomial getTombstoneKey() { | ||
auto *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey(); | ||
return mlir::heir::poly::Polynomial( | ||
static_cast<mlir::heir::poly::Polynomial::ImplType *>(pointer)); | ||
} | ||
static unsigned getHashValue(mlir::heir::poly::Polynomial val) { | ||
return mlir::heir::poly::hash_value(val); | ||
} | ||
static bool isEqual(mlir::heir::poly::Polynomial LHS, | ||
mlir::heir::poly::Polynomial RHS) { | ||
return LHS == RHS; | ||
} | ||
}; | ||
|
||
} // namespace llvm | ||
|
||
#endif // HEIR_INCLUDE_DIALECT_POLY_IR_POLYNOMIAL_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#ifndef HEIR_INCLUDE_DIALECT_POLY_IR_POLYNOMIALDETAIL_H_ | ||
#define HEIR_INCLUDE_DIALECT_POLY_IR_POLYNOMIALDETAIL_H_ | ||
|
||
#include "include/Dialect/Poly/IR/Polynomial.h" | ||
#include "llvm/ADT/ArrayRef.h" | ||
#include "llvm/Support/TrailingObjects.h" | ||
#include "mlir/Support/StorageUniquer.h" | ||
#include "mlir/Support/TypeID.h" | ||
|
||
namespace mlir { | ||
namespace heir { | ||
namespace poly { | ||
namespace detail { | ||
|
||
// A Polynomial is stored as an ordered list of monomial terms, each of which | ||
// is a tuple of coefficient and exponent. | ||
struct PolynomialStorage final | ||
: public StorageUniquer::BaseStorage, | ||
public llvm::TrailingObjects<PolynomialStorage, Monomial> { | ||
/// The hash key used for uniquing. | ||
using KeyTy = std::tuple<unsigned, ArrayRef<Monomial>>; | ||
|
||
unsigned numTerms; | ||
|
||
MLIRContext *context; | ||
|
||
/// The monomial terms for this polynomial. | ||
ArrayRef<Monomial> terms() const { | ||
return {getTrailingObjects<Monomial>(), numTerms}; | ||
} | ||
|
||
bool operator==(const KeyTy &key) const { | ||
return std::get<0>(key) == numTerms && std::get<1>(key) == terms(); | ||
} | ||
|
||
// Constructs a PolynomialStorage from a key. The context must be set by the | ||
// caller. | ||
static PolynomialStorage *construct( | ||
StorageUniquer::StorageAllocator &allocator, const KeyTy &key) { | ||
auto terms = std::get<1>(key); | ||
auto byteSize = PolynomialStorage::totalSizeToAlloc<Monomial>(terms.size()); | ||
auto *rawMem = allocator.allocate(byteSize, alignof(PolynomialStorage)); | ||
auto *res = new (rawMem) PolynomialStorage(); | ||
res->numTerms = std::get<0>(key); | ||
std::uninitialized_copy(terms.begin(), terms.end(), | ||
res->getTrailingObjects<Monomial>()); | ||
return res; | ||
} | ||
}; | ||
|
||
} // namespace detail | ||
} // namespace poly | ||
} // namespace heir | ||
} // namespace mlir | ||
|
||
MLIR_DECLARE_EXPLICIT_TYPE_ID(mlir::heir::poly::detail::PolynomialStorage) | ||
|
||
#endif // HEIR_INCLUDE_DIALECT_POLY_IR_POLYNOMIALDETAIL_H_ |
Oops, something went wrong.