41 if (ShapedType::isDynamic(int64_t(high))) {
44 os << low <<
':' << high;
59 return ll < rl || (ll == rl && lu < ru);
79 unsigned requiredBits = idx.getSignificantBits();
80 auto hash = llvm::hash_value(idx.trunc(requiredBits));
84 return llvm::hash_value(std::get<0>(r)) ^ llvm::hash_value(std::get<1>(r));
107 return std::move(sDef.value());
110std::vector<SourceRef>
112 std::vector<SourceRef> res = {root};
113 for (
const SourceRef &child : root.getAllChildren(tables,
mod)) {
114 auto recursiveChildren = getAllSourceRefs(tables,
mod, child);
115 res.insert(res.end(), recursiveChildren.begin(), recursiveChildren.end());
121 std::vector<SourceRef> res;
124 structDef == fnOp->getParentOfType<
StructDefOp>(),
"function must be within the given struct"
128 ensure(succeeded(modOp),
"could not lookup module from struct " + Twine(structDef.getName()));
130 SymbolTableCollection tables;
131 for (
auto a : fnOp.getArguments()) {
133 res.insert(res.end(), argRes.begin(), argRes.end());
140 auto createOp = dyn_cast_if_present<CreateStructOp>(selfVal.getDefiningOp());
141 ensure(createOp,
"self value should originate from struct.new operation");
143 res.insert(res.end(), selfRes.begin(), selfRes.end());
150 std::vector<SourceRef> res;
153 fieldDef->getParentOfType<
StructDefOp>() == structDef,
"Field " + Twine(fieldDef.getName()) +
154 " is not a field of struct " +
155 Twine(structDef.getName())
158 ensure(succeeded(modOp),
"could not lookup module from struct " + Twine(structDef.getName()));
161 BlockArgument self = constrainFnOp.getArguments().front();
164 SymbolTableCollection tables;
170 return std::get<FeltConstantOp>(*constantVal).getType();
172 return std::get<arith::ConstantIndexOp>(*constantVal).getType();
174 return std::get<ConstReadOp>(*constantVal).getType();
176 int array_derefs = 0;
177 int idx = fieldRefs.size() - 1;
178 while (idx >= 0 && fieldRefs[idx].
isIndex()) {
183 Type currTy =
nullptr;
185 currTy = fieldRefs[idx].getField().getType();
190 while (array_derefs > 0) {
191 currTy = dyn_cast<ArrayType>(currTy).getElementType();
203 if (root != prefix.root || fieldRefs.size() < prefix.fieldRefs.size()) {
206 for (
size_t i = 0; i < prefix.fieldRefs.size(); i++) {
207 if (fieldRefs[i] != prefix.fieldRefs[i]) {
218 std::vector<SourceRefIndex> suffix;
219 for (
size_t i = prefix.fieldRefs.size(); i < fieldRefs.size(); i++) {
220 suffix.push_back(fieldRefs[i]);
230 if (failed(suffix)) {
234 auto newSignalUsage = other;
235 newSignalUsage.fieldRefs.insert(newSignalUsage.fieldRefs.end(), suffix->begin(), suffix->end());
236 return newSignalUsage;
239std::vector<SourceRef>
241 std::vector<SourceRef> res;
243 for (int64_t i = 0; i < arrayTy.getDimSize(0); i++) {
245 res.push_back(childRef);
255 std::vector<SourceRef> res;
263 auto structDefCopy = structDefRes;
265 tables, SymbolRefAttr::get(f.getContext(), f.getSymNameAttr()), std::move(structDefCopy),
268 ensure(succeeded(fieldLookup),
"could not get SymbolLookupResult of existing FieldDefOp");
272 res.push_back(childRef);
277std::vector<SourceRef>
280 if (
auto structTy = dyn_cast<StructType>(ty)) {
282 }
else if (
auto arrayType = dyn_cast<ArrayType>(ty)) {
295 auto constRead = std::get<ConstReadOp>(*constantVal);
296 auto structDefOp = constRead->getParentOfType<
StructDefOp>();
297 ensure(structDefOp,
"struct template should have a struct parent");
298 os <<
'@' << structDefOp.getName() <<
"<[@" << constRead.getConstName() <<
"]>";
307 for (
auto f : fieldRefs) {
308 os <<
"[" << f <<
"]";
319 return (root == rhs.root) && (fieldRefs == rhs.fieldRefs) && (constantVal == rhs.constantVal);
331 return lhsInt < rhsInt;
341 return lhsVal < rhsVal;
350 StringRef lhsName = std::get<ConstReadOp>(*constantVal).getConstName();
351 StringRef rhsName = std::get<ConstReadOp>(*rhs.constantVal).getConstName();
352 return lhsName.compare(rhsName) < 0;
370 }
else if (lhsOp > rhsOp) {
374 llvm_unreachable(
"unhandled operator< case");
377 for (
size_t i = 0; i < fieldRefs.size() && i < rhs.fieldRefs.size(); i++) {
378 if (fieldRefs[i] < rhs.fieldRefs[i]) {
380 }
else if (fieldRefs[i] > rhs.fieldRefs[i]) {
384 return fieldRefs.size() < rhs.fieldRefs.size();
397 for (
auto f : val.fieldRefs) {
412 insert(rhs.begin(), rhs.end());
418 std::vector<SourceRef> sortedRefs(rhs.begin(), rhs.end());
419 std::sort(sortedRefs.begin(), sortedRefs.end());
420 for (
auto it = sortedRefs.begin(); it != sortedRefs.end();) {
423 if (it != sortedRefs.end()) {
This file implements helper methods for constructing DynamicAPInts.
This file defines methods symbol lookup across LLZK operations and included files.
bool isIndexRange() const
bool operator<(const SourceRefIndex &rhs) const
component::FieldDefOp getField() const
SourceRefIndex(component::FieldDefOp f)
llvm::DynamicAPInt getIndex() const
void print(mlir::raw_ostream &os) const
IndexRange getIndexRange() const
SourceRefSet & join(const SourceRefSet &rhs)
A reference to a "source", which is the base value from which other SSA values are derived.
bool isBlockArgument() const
llvm::DynamicAPInt getConstantIndexValue() const
std::vector< SourceRef > getAllChildren(mlir::SymbolTableCollection &tables, mlir::ModuleOp mod) const
Get all direct children of this SourceRef, assuming this ref is not a scalar.
void print(mlir::raw_ostream &os) const
mlir::FailureOr< std::vector< SourceRefIndex > > getSuffix(const SourceRef &prefix) const
If prefix is a valid prefix of this reference, return the suffix that remains after removing the pref...
bool operator==(const SourceRef &rhs) const
bool isConstantFelt() const
component::CreateStructOp getCreateStructOp() const
bool isValidPrefix(const SourceRef &prefix) const
Returns true iff prefix is a valid prefix of this reference.
bool isConstantIndex() const
SourceRef createChild(SourceRefIndex r) const
mlir::BlockArgument getBlockArgument() const
llvm::DynamicAPInt getConstantValue() const
static std::vector< SourceRef > getAllSourceRefs(mlir::SymbolTableCollection &tables, mlir::ModuleOp mod, SourceRef root)
Produce all possible SourceRefs that are present starting from the given root.
bool operator<(const SourceRef &rhs) const
SourceRef(mlir::BlockArgument b)
mlir::FailureOr< SourceRef > translate(const SourceRef &prefix, const SourceRef &other) const
Create a new reference with prefix replaced with other iff prefix is a valid prefix for this referenc...
bool isTemplateConstant() const
llvm::DynamicAPInt getConstantFeltValue() const
unsigned getInputNum() const
bool isConstantInt() const
bool isCreateStructOp() const
mlir::Type getType() const
static constexpr ::llvm::StringLiteral getOperationName()
::llzk::function::FuncDefOp getConstrainFuncOp()
Gets the FuncDefOp that defines the constrain function in this structure, if present,...
::mlir::FailureOr< SymbolLookupResult< StructDefOp > > getDefinition(::mlir::SymbolTableCollection &symbolTable, ::mlir::Operation *op) const
Gets the struct op that defines this struct.
::mlir::Value getSelfValueFromCompute()
Return the "self" value (i.e.
bool isStructCompute()
Return true iff the function is within a StructDefOp and named FUNC_NAME_COMPUTE.
void ensure(bool condition, const llvm::Twine &errMsg)
FailureOr< ModuleOp > getRootModule(Operation *from)
Interval operator<<(const Interval &lhs, const Interval &rhs)
std::vector< SourceRef > getAllChildren(SymbolTableCollection &tables, ModuleOp, ArrayType arrayTy, SourceRef root)
mlir::FailureOr< SymbolLookupResultUntyped > lookupSymbolIn(mlir::SymbolTableCollection &tables, mlir::SymbolRefAttr symbol, Within &&lookupWithin, mlir::Operation *origin, bool reportMissing=true)
APSInt toAPSInt(const DynamicAPInt &i)
ExpressionValue mod(llvm::SMTSolverRef solver, const ExpressionValue &lhs, const ExpressionValue &rhs)
SymbolLookupResult< StructDefOp > getStructDef(SymbolTableCollection &tables, ModuleOp mod, StructType ty)
Lookup a StructDefOp from a given StructType.
size_t operator()(const SourceRefIndex &c) const
size_t operator()(const SourceRef &val) const