LLZK 3.0.0
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
SourceRefLattice.h
Go to the documentation of this file.
1//===-- SourceRefLattice.h -----------------------------------*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
10#pragma once
11
16
17#include <mlir/Analysis/DataFlow/DenseAnalysis.h>
18
19#include <llvm/ADT/PointerUnion.h>
20
21namespace llzk {
22
24using TranslationMap = std::unordered_map<SourceRef, SourceRefLatticeValue, SourceRef::Hash>;
25
28 : public dataflow::AbstractLatticeValue<SourceRefLatticeValue, SourceRefSet> {
31 using ScalarTy = SourceRefSet;
39 using ArrayTy = std::vector<std::unique_ptr<SourceRefLatticeValue>>;
40
41public:
42 explicit SourceRefLatticeValue(ScalarTy s) : Base(std::move(s)) {}
43 explicit SourceRefLatticeValue(SourceRef r) : Base(ScalarTy {std::move(r)}) {}
44 SourceRefLatticeValue() : Base(ScalarTy {}) {}
49 virtual ~SourceRefLatticeValue() = default;
50
51 // Create an empty array of the given shape.
52 explicit SourceRefLatticeValue(mlir::ArrayRef<int64_t> shape) : Base(shape) {}
53
54 const SourceRef &getSingleValue() const {
55 ensure(isSingleValue(), "not a single value");
56 return *getScalarValue().begin();
57 }
58
61 mlir::FailureOr<llvm::DynamicAPInt> getConstantValue() const {
62 if (isSingleValue()) {
64 }
65 return mlir::failure();
66 }
67
70 mlir::FailureOr<llvm::DynamicAPInt> getConstantValue(const Field &field) const {
71 if (isSingleValue()) {
72 return getSingleValue().getConstantValue(field);
73 }
74 return mlir::failure();
75 }
76
79
83 mlir::ChangeResult insert(const SourceRef &rhs);
84
86 mlir::ChangeResult remove(const SourceRef &ref);
87
91 std::pair<SourceRefLatticeValue, mlir::ChangeResult>
92 translate(const TranslationMap &translation) const;
93
95 std::pair<SourceRefLatticeValue, mlir::ChangeResult>
96 replacePrefixes(const TranslationMap &translation) const;
97
103 mlir::ChangeResult write(
104 const std::vector<SourceRefIndex> &indices, const SourceRefLatticeValue &rhs,
105 bool joinWithExisting = false
106 );
107
114 mlir::FailureOr<std::pair<SourceRefLatticeValue, mlir::ChangeResult>>
116
120 mlir::FailureOr<std::pair<SourceRefLatticeValue, mlir::ChangeResult>>
121 referencePodRecord(mlir::StringAttr recordName) const;
122
125 mlir::FailureOr<std::pair<SourceRefLatticeValue, mlir::ChangeResult>>
126 extract(const std::vector<SourceRefIndex> &indices) const;
127
128protected:
131 mlir::ChangeResult translateScalar(const TranslationMap &translation);
132
134 mlir::ChangeResult replacePrefixesScalar(const TranslationMap &translation);
135
138 virtual mlir::FailureOr<std::pair<SourceRefLatticeValue, mlir::ChangeResult>>
140 llvm::function_ref<mlir::FailureOr<SourceRef>(const SourceRef &)> transform
141 ) const;
142};
143
146public:
148 // mlir::Value is used for read-like operations that create references in their results,
149 // mlir::Operation* is used for write-like operations that reference values as their destinations
150 using ValueTy = llvm::PointerUnion<mlir::Value, mlir::Operation *>;
151 using Ref2Val = mlir::DenseMap<SourceRef, mlir::DenseSet<ValueTy>>;
152
153 /* Static utilities */
154
159 static mlir::FailureOr<SourceRef> getSourceRef(mlir::Value val);
161
162 using AbstractSparseLattice::AbstractSparseLattice;
163
164 mlir::ChangeResult join(const AbstractSparseLattice &rhs) override;
165 mlir::ChangeResult meet(const AbstractSparseLattice &rhs) override;
166 void print(mlir::raw_ostream &os) const override;
167
168 const LatticeValue &getValue() const { return value; }
169
170 mlir::ChangeResult setValue(const LatticeValue &newValue);
171 mlir::ChangeResult setValue(const SourceRef &ref);
172
173private:
174 LatticeValue value;
175};
176
177} // namespace llzk
178
179namespace llvm {
180class raw_ostream;
181
182raw_ostream &operator<<(raw_ostream &os, llvm::PointerUnion<mlir::Value, mlir::Operation *> ptr);
183} // namespace llvm
This file provides LLZK's sparse forward data-flow analysis compatibility layer.
Information about the prime finite field used for the interval analysis.
Definition Field.h:36
A value at a given point of the SourceRefLattice.
mlir::ChangeResult write(const std::vector< SourceRefIndex > &indices, const SourceRefLatticeValue &rhs, bool joinWithExisting=false)
Update the element or subarray selected by indices.
virtual ~SourceRefLatticeValue()=default
SourceRefLatticeValue & operator=(const SourceRefLatticeValue &)=default
mlir::FailureOr< llvm::DynamicAPInt > getConstantValue() const
Return the numeric value of a single constant reference, or failure otherwise.
mlir::FailureOr< llvm::DynamicAPInt > getConstantValue(const Field &field) const
Return a single constant reference's value using the supplied analysis field.
mlir::FailureOr< std::pair< SourceRefLatticeValue, mlir::ChangeResult > > referencePodRecord(mlir::StringAttr recordName) const
Add the given pod recordName to the SourceRefs contained within this value.
mlir::ChangeResult remove(const SourceRef &ref)
Remove ref from this value's reference set or, for an array, from every element.
SourceRefLatticeValue(SourceRefLatticeValue &&)=default
mlir::ChangeResult replacePrefixesScalar(const TranslationMap &translation)
Replace matching prefixes in a scalar value without dropping unmatched references.
SourceRefLatticeValue(mlir::ArrayRef< int64_t > shape)
mlir::FailureOr< std::pair< SourceRefLatticeValue, mlir::ChangeResult > > referenceMember(SymbolLookupResult< component::MemberDefOp > memberRef) const
Add the given memberRef to the SourceRefs contained within this value.
virtual mlir::FailureOr< std::pair< SourceRefLatticeValue, mlir::ChangeResult > > elementwiseTransform(llvm::function_ref< mlir::FailureOr< SourceRef >(const SourceRef &)> transform) const
Perform a recursive transformation over all elements of this value and return a new value with the mo...
const SourceRef & getSingleValue() const
mlir::ChangeResult insert(const SourceRef &rhs)
Directly insert the ref into this value.
SourceRefLatticeValue(const SourceRefLatticeValue &)=default
std::pair< SourceRefLatticeValue, mlir::ChangeResult > translate(const TranslationMap &translation) const
Translate contained references using translation and return the transformed value.
mlir::FailureOr< std::pair< SourceRefLatticeValue, mlir::ChangeResult > > extract(const std::vector< SourceRefIndex > &indices) const
Perform an array.extract or array.read operation, depending on how many indices are provided.
mlir::ChangeResult translateScalar(const TranslationMap &translation)
Translate this value using the translation map, assuming this value is a scalar.
SourceRefLatticeValue & operator=(SourceRefLatticeValue &&)=default
std::pair< SourceRefLatticeValue, mlir::ChangeResult > replacePrefixes(const TranslationMap &translation) const
Replace matching SourceRef prefixes and leave unmatched references unchanged.
Sparse SSA-value lattice for SourceRef propagation.
mlir::ChangeResult join(const AbstractSparseLattice &rhs) override
mlir::ChangeResult setValue(const LatticeValue &newValue)
mlir::DenseMap< SourceRef, mlir::DenseSet< ValueTy > > Ref2Val
mlir::ChangeResult meet(const AbstractSparseLattice &rhs) override
static SourceRefLatticeValue getDefaultValue(ValueTy v)
void print(mlir::raw_ostream &os) const override
static mlir::FailureOr< SourceRef > getSourceRef(mlir::Value val)
If val is the source of other values (i.e., a block argument, an allocation-like op result,...
const LatticeValue & getValue() const
llvm::PointerUnion< mlir::Value, mlir::Operation * > ValueTy
SourceRefLatticeValue LatticeValue
A reference to a "source", which is the base value from which other SSA values are derived.
Definition SourceRef.h:152
mlir::FailureOr< llvm::DynamicAPInt > getConstantValue(const Field &field) const
Reduce a felt constant's declared-field representative into the supplied analysis field.
raw_ostream & operator<<(raw_ostream &os, llvm::PointerUnion< mlir::Value, mlir::Operation * > ptr)
mlir::dataflow::AbstractSparseLattice AbstractSparseLattice
void ensure(bool condition, const llvm::Twine &errMsg)
std::unordered_map< SourceRef, SourceRefLatticeValue, SourceRef::Hash > TranslationMap