mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-28 18:16:06 +00:00

This attributes is intended cover the current set of use cases that abuse DenseElementsAttr, e.g. when the data is large. Using resources for large data is one of the major reasons why they were added; e.g. they can be deallocated mid-compilation, they support a wide variety of data origins (e.g, heap allocated, mmap'd, etc.), they can support mutation, etc. I considered at length not having a builtin variant of this, and instead having multiple versions of this attribute for dialects that are interested, but they all boiled down to the exact same attribute definition. Given the generality of this attribute, it feels more aligned to keep it next to DenseArrayAttr (given that DenseArrayAttr covers the "small" case, and DenseResourcesElementsAttr covers the "large" case). The underlying infra used to build this attribute is general, and having a builtin attribute doesn't preclude users from defining their own when it makes sense (they can even share a blob manager with the builtin dialect to avoid data duplication). Differential Revision: https://reviews.llvm.org/D130022
65 lines
2.2 KiB
C++
65 lines
2.2 KiB
C++
//===- DialectResourceBlobManager.cpp - Dialect Blob Management -----------===//
|
|
//
|
|
// 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/IR/DialectResourceBlobManager.h"
|
|
#include "llvm/ADT/SmallString.h"
|
|
|
|
using namespace mlir;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// DialectResourceBlobManager
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
auto DialectResourceBlobManager::lookup(StringRef name) -> BlobEntry * {
|
|
llvm::sys::SmartScopedReader<true> reader(blobMapLock);
|
|
|
|
auto it = blobMap.find(name);
|
|
return it != blobMap.end() ? &it->second : nullptr;
|
|
}
|
|
|
|
void DialectResourceBlobManager::update(StringRef name,
|
|
AsmResourceBlob &&newBlob) {
|
|
BlobEntry *entry = lookup(name);
|
|
assert(entry && "`update` expects an existing entry for the provided name");
|
|
entry->setBlob(std::move(newBlob));
|
|
}
|
|
|
|
auto DialectResourceBlobManager::insert(StringRef name,
|
|
Optional<AsmResourceBlob> blob)
|
|
-> BlobEntry & {
|
|
llvm::sys::SmartScopedWriter<true> writer(blobMapLock);
|
|
|
|
// Functor used to attempt insertion with a given name.
|
|
auto tryInsertion = [&](StringRef name) -> BlobEntry * {
|
|
auto it = blobMap.try_emplace(name, BlobEntry());
|
|
if (it.second) {
|
|
it.first->second.initialize(it.first->getKey(), std::move(blob));
|
|
return &it.first->second;
|
|
}
|
|
return nullptr;
|
|
};
|
|
|
|
// Try inserting with the name provided by the user.
|
|
if (BlobEntry *entry = tryInsertion(name))
|
|
return *entry;
|
|
|
|
// If an entry already exists for the user provided name, tweak the name and
|
|
// re-attempt insertion until we find one that is unique.
|
|
llvm::SmallString<32> nameStorage(name);
|
|
nameStorage.push_back('_');
|
|
size_t nameCounter = 1;
|
|
do {
|
|
Twine(nameCounter++).toVector(nameStorage);
|
|
|
|
// Try inserting with the new name.
|
|
if (BlobEntry *entry = tryInsertion(nameStorage))
|
|
return *entry;
|
|
nameStorage.resize(name.size() + 1);
|
|
} while (true);
|
|
}
|