RFC: https://discourse.llvm.org/t/rfc-a-poly-dialect-for-polynomial-arithmetic/73891 This PR implements the minimal work needed to represent the polynomial type such that it can be tested with `lit`. In this PR: - Dialect shell - `Polynomial` data structure needed for folding - Polynomial attributes (`PolynomialAttr` and `RingAttr` which store a polynomial) - `polynomial.polynomial` type - Basic lit tests --------- Co-authored-by: Jeremy Kun <j2kun@users.noreply.github.com>
97 lines
3.0 KiB
C++
97 lines
3.0 KiB
C++
//===- Polynomial.cpp - MLIR storage type for static Polynomial -*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Dialect/Polynomial/IR/Polynomial.h"
|
|
|
|
#include "mlir/Support/LogicalResult.h"
|
|
#include "llvm/ADT/APInt.h"
|
|
#include "llvm/ADT/SmallString.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/ADT/Twine.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
namespace mlir {
|
|
namespace polynomial {
|
|
|
|
FailureOr<Polynomial> Polynomial::fromMonomials(ArrayRef<Monomial> monomials) {
|
|
// A polynomial's terms are canonically stored in order of increasing degree.
|
|
auto monomialsCopy = llvm::SmallVector<Monomial>(monomials);
|
|
std::sort(monomialsCopy.begin(), monomialsCopy.end());
|
|
|
|
// Ensure non-unique exponents are not present. Since we sorted the list by
|
|
// exponent, a linear scan of adjancent monomials suffices.
|
|
if (std::adjacent_find(monomialsCopy.begin(), monomialsCopy.end(),
|
|
[](const Monomial &lhs, const Monomial &rhs) {
|
|
return lhs.exponent == rhs.exponent;
|
|
}) != monomialsCopy.end()) {
|
|
return failure();
|
|
}
|
|
|
|
return Polynomial(monomialsCopy);
|
|
}
|
|
|
|
Polynomial Polynomial::fromCoefficients(ArrayRef<int64_t> coeffs) {
|
|
llvm::SmallVector<Monomial> monomials;
|
|
auto size = coeffs.size();
|
|
monomials.reserve(size);
|
|
for (size_t i = 0; i < size; i++) {
|
|
monomials.emplace_back(coeffs[i], i);
|
|
}
|
|
auto result = Polynomial::fromMonomials(monomials);
|
|
// Construction guarantees unique exponents, so the failure mode of
|
|
// fromMonomials can be bypassed.
|
|
assert(succeeded(result));
|
|
return result.value();
|
|
}
|
|
|
|
void Polynomial::print(raw_ostream &os, ::llvm::StringRef separator,
|
|
::llvm::StringRef exponentiation) const {
|
|
bool first = true;
|
|
for (const Monomial &term : terms) {
|
|
if (first) {
|
|
first = false;
|
|
} else {
|
|
os << separator;
|
|
}
|
|
std::string coeffToPrint;
|
|
if (term.coefficient == 1 && term.exponent.uge(1)) {
|
|
coeffToPrint = "";
|
|
} else {
|
|
llvm::SmallString<16> coeffString;
|
|
term.coefficient.toStringSigned(coeffString);
|
|
coeffToPrint = coeffString.str();
|
|
}
|
|
|
|
if (term.exponent == 0) {
|
|
os << coeffToPrint;
|
|
} else if (term.exponent == 1) {
|
|
os << coeffToPrint << "x";
|
|
} else {
|
|
llvm::SmallString<16> expString;
|
|
term.exponent.toStringSigned(expString);
|
|
os << coeffToPrint << "x" << exponentiation << expString;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Polynomial::print(raw_ostream &os) const { print(os, " + ", "**"); }
|
|
|
|
std::string Polynomial::toIdentifier() const {
|
|
std::string result;
|
|
llvm::raw_string_ostream os(result);
|
|
print(os, "_", "");
|
|
return os.str();
|
|
}
|
|
|
|
unsigned Polynomial::getDegree() const {
|
|
return terms.back().exponent.getZExtValue();
|
|
}
|
|
|
|
} // namespace polynomial
|
|
} // namespace mlir
|