12#include <mlir/IR/Builders.h>
14#include <llvm/ADT/DenseMap.h>
26 llvm::DenseMap<mlir::ArrayAttr, llvm::SmallVector<int64_t>>
shapes;
31 shapes.remove_if([](
const auto &entry) {
return !entry.first.empty(); });
53 static constexpr size_t allocationCleanupInterval = 4096;
55 mlir::Builder builder;
56 llvm::SmallVector<std::weak_ptr<DiscoveryAggregate>> allocations;
58 static bool startsWith(mlir::ArrayAttr path, llvm::ArrayRef<mlir::Attribute> prefix) {
59 return path.size() >= prefix.size() &&
60 llvm::equal(path.getValue().take_front(prefix.size()), prefix);
68 if (allocations.size() >= allocationCleanupInterval &&
69 allocations.size() % allocationCleanupInterval == 0) {
70 llvm::erase_if(allocations, [](
const auto &allocation) {
return allocation.expired(); });
73 value.
aggregate = std::make_shared<DiscoveryAggregate>();
81 llvm::erase_if(allocations, [](
auto &allocation) {
82 if (
auto leaves = allocation.lock()) {
107 return source.aggregate->leaves.lookup(builder.getArrayAttr(path));
110 for (
auto [key, value] :
source.aggregate->leaves) {
111 if (startsWith(key, path)) {
112 result.aggregate->leaves[builder.getArrayAttr(key.getValue().drop_front(path.size()))] =
116 for (
const auto &[key, shape] :
source.aggregate->shapes) {
117 if (startsWith(key, path)) {
118 result.aggregate->shapes[builder.getArrayAttr(key.getValue().drop_front(path.size()))] =
123 auto root =
source.aggregate->shapes.find(builder.getArrayAttr({}));
124 if (root !=
source.aggregate->shapes.end() && path.size() < root->second.size() &&
125 llvm::all_of(path, [](mlir::Attribute part) {
126 return llvm::isa<mlir::IntegerAttr>(part);
128 result.aggregate->shapes[builder.getArrayAttr({})] =
129 llvm::SmallVector<int64_t>(llvm::ArrayRef(root->second).drop_front(path.size()));
137 llvm::ArrayRef<mlir::Attribute> path = {}
139 value.
aggregate->shapes[builder.getArrayAttr(path)] = llvm::SmallVector<int64_t>(shape);
145 auto it = value.
aggregate->shapes.find(builder.getArrayAttr({}));
146 if (it != value.
aggregate->shapes.end()) {
155 const DiscoveryValue &destination, llvm::ArrayRef<mlir::Attribute> path,
163 destination.
aggregate->leaves.remove_if([path](
const auto &entry) {
164 return startsWith(entry.first, path);
169 destination.
aggregate->shapes.remove_if([path](
const auto &entry) {
170 return startsWith(entry.first, path);
172 for (
const auto &[key, shape] : snapshot.
shapes) {
173 llvm::SmallVector<mlir::Attribute> target(path);
174 llvm::append_range(target, key.getValue());
175 destination.
aggregate->shapes[builder.getArrayAttr(target)] = shape;
177 for (
auto [key, constant] : snapshot.
leaves) {
178 llvm::SmallVector<mlir::Attribute> target(path);
179 llvm::append_range(target, key.getValue());
180 destination.
aggregate->leaves[builder.getArrayAttr(target)] = constant;
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation source
void write(const DiscoveryValue &destination, llvm::ArrayRef< mlir::Attribute > path, const DiscoveryValue &value)
Replace a subtree, clearing old facts even when the new value is unknown.
DiscoveryStorage(mlir::MLIRContext *context)
DiscoveryValue read(const DiscoveryValue &source, llvm::ArrayRef< mlir::Attribute > path, bool aggregate)
Read a scalar leaf or snapshot an aggregate subtree into an independent root.
DiscoveryValue create()
Allocate an aggregate with no known leaves.
void forget(const DiscoveryValue &value)
Forget the contents of a potentially modified or escaping local aggregate.
void invalidate()
Drop memory facts at an unknown control-flow or call boundary.
llvm::ArrayRef< int64_t > getShape(const DiscoveryValue &value)
Return concrete root dimensions when available, including after value copies.
void setShape(const DiscoveryValue &value, llvm::ArrayRef< int64_t > shape, llvm::ArrayRef< mlir::Attribute > path={})
Record dimensions at an array root or a nested POD record path.
Common interface for constant parameter-like symbol operations that can be defined within a TemplateO...
llvm::DenseMap< mlir::ArrayAttr, mlir::Attribute > DiscoveryLeaves
Sparse known scalar leaves of a local aggregate, indexed by record/array paths.
Scalar contents and concrete array shapes, including nested aggregate roots.
void invalidate()
Writes may replace nested arrays, but cannot resize the root allocation.
llvm::DenseMap< mlir::ArrayAttr, llvm::SmallVector< int64_t > > shapes
A scalar constant or a local aggregate identity. Missing leaves are unknown.
DiscoveryValue(mlir::Attribute value)
std::shared_ptr< DiscoveryAggregate > aggregate
bool operator==(const DiscoveryValue &other) const