15#include <mlir/IR/BuiltinAttributes.h>
16#include <mlir/IR/BuiltinOps.h>
17#include <mlir/Support/LLVM.h>
19#include <llvm/ADT/DenseMap.h>
20#include <llvm/ADT/DynamicAPInt.h>
21#include <llvm/ADT/SmallSet.h>
22#include <llvm/Support/LogicalResult.h>
23#include <llvm/Support/SMTAPI.h>
49 static llvm::FailureOr<std::reference_wrapper<const Field>>
70 llvm::DynamicAPInt
prime()
const {
return primeMod; }
73 llvm::DynamicAPInt
half()
const {
return halfPrime; }
76 inline llvm::DynamicAPInt
felt(
int i)
const {
return reduce(i); }
79 inline llvm::DynamicAPInt
zero()
const {
return felt(0); }
82 inline llvm::DynamicAPInt
one()
const {
return felt(1); }
88 llvm::DynamicAPInt
inv(
const llvm::DynamicAPInt &i)
const;
93 llvm::DynamicAPInt
reduce(
const llvm::DynamicAPInt &i)
const;
94 inline llvm::DynamicAPInt
reduce(int64_t i)
const {
return reduce(llvm::DynamicAPInt(i)); }
100 llvm::DynamicAPInt
toSigned(
const llvm::DynamicAPInt &i)
const;
103 inline unsigned bitWidth()
const {
return bitwidth; }
105 inline llvm::StringRef
name()
const {
return primeName; }
109 return solver->mkSymbol(
name, solver->getBitvectorSort(
bitWidth()));
116 return lhs.primeMod == rhs.primeMod;
125 return std::tie(lhs.primeMod, lhs.primeName, lhs.bitwidth, lhs.halfPrime) <
126 std::tie(rhs.primeMod, rhs.primeName, rhs.bitwidth, rhs.halfPrime);
130 Field(std::string_view primeStr, llvm::StringRef
name);
131 Field(
const llvm::DynamicAPInt &primeInt, llvm::StringRef
name);
134 llvm::StringRef primeName;
135 llvm::DynamicAPInt primeMod, halfPrime;
139 static void initKnownFields();
157using FieldRef = std::reference_wrapper<const Field>;
This file implements helpers for DynamicAPInt operations and conversions that LLVM does not provide.
Information about the prime finite field used for the interval analysis.
static void addField(llvm::StringRef fieldName, const llvm::DynamicAPInt &prime, EmitErrorFn errFn)
Add a new field to the set of available prime fields.
static void addField(llvm::StringRef fieldName, llvm::StringRef primeStr, EmitErrorFn errFn)
llvm::DynamicAPInt half() const
Returns ceil(p / 2), the first negative signed representative.
mlir::IntegerAttr getPrimeAttr(mlir::MLIRContext *context, unsigned bitWidth) const
Return the field prime modulus materialized as an integer attribute at bitWidth.
static llvm::FailureOr< std::reference_wrapper< const Field > > tryGetField(llvm::StringRef fieldName)
Get a Field from a given field name string, or failure if the field is not defined.
friend bool operator==(const Field &lhs, const Field &rhs)
Field(const Field &)=default
llvm::DynamicAPInt zero() const
Returns the zero field element.
llvm::DynamicAPInt toSigned(const llvm::DynamicAPInt &i) const
Converts a canonical field element to its signed integer representation: toSigned(f) = f if f < field...
llvm::DynamicAPInt prime() const
For the prime field p, returns p.
llvm::DynamicAPInt reduce(const llvm::DynamicAPInt &i) const
Returns the canonical representative of i mod p in [0, p).
llvm::StringRef name() const
llvm::DynamicAPInt one() const
Returns the unit field element.
llvm::DynamicAPInt felt(int i) const
Returns i as a signed field element.
unsigned bitWidth() const
Width sufficient for the modulus and its representatives, independent of literal storage.
friend bool operator<(const Field &lhs, const Field &rhs)
llvm::DynamicAPInt reduce(int64_t i) const
llvm::DynamicAPInt inv(const llvm::DynamicAPInt &i) const
Returns the multiplicative inverse of i in prime field p.
llvm::SMTExprRef createSymbol(const llvm::SMTSolverRef &solver, const char *name) const
Create a SMT solver symbol with the current field's bitwidth.
static const Field & getField(llvm::StringRef fieldName)
static llvm::LogicalResult verifyFieldDefined(llvm::StringRef fieldName, EmitErrorFn errFn)
Search for a field with the given name, reporting an error if the field is not found.
static const Field & getField(llvm::StringRef fieldName, EmitErrorFn errFn)
Get a Field from a given field name string.
Field(Field &&) noexcept=default
llvm::DynamicAPInt maxVal() const
Returns p - 1, which is the max value possible in a prime field described by p.
std::reference_wrapper< const Field > FieldRef
Typealias for a stable reference to a known Field.
hash_code hashDynamicAPInt(const DynamicAPInt &value)
llvm::function_ref< InFlightDiagnosticWrapper()> EmitErrorFn
Callback to produce an error diagnostic.
LogicalResult addSpecifiedFields(ModuleOp modOp)
llvm::SmallSet< FieldRef, 2 > FieldSet
Typealias for a set of Fields.
std::optional< std::reference_wrapper< const Field > > tryDetectSpecifiedField(mlir::Operation *root)
Try to detect a uniquely used field from the enclosing LLZK module.
mlir::LogicalResult collectFields(mlir::Operation *root, FieldSet &fields, bool silent=true)
Collects all the fields used in a circuit.
Hash the prime modulus (consistent with the equality operator).
size_t operator()(const Field &field) const