mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-25 10:38:44 +00:00
IR: Extract set logic from Instruction attachments, NFC
Extract the set logic for metadata attachments from `Instruction` so it can be reused for `Function` (PR23340). This data structure makes a `SmallVector<>` look (a little) like a map, just doing the bare minimum to support the `Instruction` (and soon, `Function`) metadata API. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235769 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
39789f81ab
commit
223d9cfd30
@ -852,6 +852,44 @@ template <class NodeTy> struct MDNodeInfo {
|
|||||||
#define HANDLE_MDNODE_LEAF(CLASS) typedef MDNodeInfo<CLASS> CLASS##Info;
|
#define HANDLE_MDNODE_LEAF(CLASS) typedef MDNodeInfo<CLASS> CLASS##Info;
|
||||||
#include "llvm/IR/Metadata.def"
|
#include "llvm/IR/Metadata.def"
|
||||||
|
|
||||||
|
/// \brief Map-like storage for metadata attachments.
|
||||||
|
class MDAttachmentMap {
|
||||||
|
SmallVector<std::pair<unsigned, TrackingMDNodeRef>, 2> Attachments;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool empty() const { return Attachments.empty(); }
|
||||||
|
size_t size() const { return Attachments.size(); }
|
||||||
|
|
||||||
|
/// \brief Get a particular attachment (if any).
|
||||||
|
MDNode *lookup(unsigned ID) const;
|
||||||
|
|
||||||
|
/// \brief Set an attachment to a particular node.
|
||||||
|
///
|
||||||
|
/// Set the \c ID attachment to \c MD, replacing the current attachment at \c
|
||||||
|
/// ID (if anyway).
|
||||||
|
void set(unsigned ID, MDNode &MD);
|
||||||
|
|
||||||
|
/// \brief Remove an attachment.
|
||||||
|
///
|
||||||
|
/// Remove the attachment at \c ID, if any.
|
||||||
|
void erase(unsigned ID);
|
||||||
|
|
||||||
|
/// \brief Copy out all the attachments.
|
||||||
|
///
|
||||||
|
/// Copies all the current attachments into \c Result, sorting by attachment
|
||||||
|
/// ID. This function does \em not clear \c Result.
|
||||||
|
void getAll(SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const;
|
||||||
|
|
||||||
|
/// \brief Erase matching attachments.
|
||||||
|
///
|
||||||
|
/// Erases all attachments matching the \c shouldRemove predicate.
|
||||||
|
template <class PredTy> void remove_if(PredTy shouldRemove) {
|
||||||
|
Attachments.erase(
|
||||||
|
std::remove_if(Attachments.begin(), Attachments.end(), shouldRemove),
|
||||||
|
Attachments.end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class LLVMContextImpl {
|
class LLVMContextImpl {
|
||||||
public:
|
public:
|
||||||
/// OwnedModules - The set of modules instantiated in this context, and which
|
/// OwnedModules - The set of modules instantiated in this context, and which
|
||||||
@ -952,9 +990,7 @@ public:
|
|||||||
StringMap<unsigned> CustomMDKindNames;
|
StringMap<unsigned> CustomMDKindNames;
|
||||||
|
|
||||||
/// Collection of per-instruction metadata used in this context.
|
/// Collection of per-instruction metadata used in this context.
|
||||||
DenseMap<const Instruction *,
|
DenseMap<const Instruction *, MDAttachmentMap> InstructionMetadata;
|
||||||
SmallVector<std::pair<unsigned, TrackingMDNodeRef>, 2>>
|
|
||||||
InstructionMetadata;
|
|
||||||
|
|
||||||
/// DiscriminatorTable - This table maps file:line locations to an
|
/// DiscriminatorTable - This table maps file:line locations to an
|
||||||
/// integer representing the next DWARF path discriminator to assign to
|
/// integer representing the next DWARF path discriminator to assign to
|
||||||
|
@ -975,6 +975,50 @@ StringRef NamedMDNode::getName() const {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Instruction Metadata method implementations.
|
// Instruction Metadata method implementations.
|
||||||
//
|
//
|
||||||
|
void MDAttachmentMap::set(unsigned ID, MDNode &MD) {
|
||||||
|
for (auto &I : Attachments)
|
||||||
|
if (I.first == ID) {
|
||||||
|
I.second.reset(&MD);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Attachments.emplace_back(std::piecewise_construct, std::make_tuple(ID),
|
||||||
|
std::make_tuple(&MD));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDAttachmentMap::erase(unsigned ID) {
|
||||||
|
if (empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Common case is one/last value.
|
||||||
|
if (Attachments.back().first == ID) {
|
||||||
|
Attachments.pop_back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto I = Attachments.begin(), E = std::prev(Attachments.end()); I != E;
|
||||||
|
++I)
|
||||||
|
if (I->first == ID) {
|
||||||
|
*I = std::move(Attachments.back());
|
||||||
|
Attachments.pop_back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MDNode *MDAttachmentMap::lookup(unsigned ID) const {
|
||||||
|
for (const auto &I : Attachments)
|
||||||
|
if (I.first == ID)
|
||||||
|
return I.second;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MDAttachmentMap::getAll(
|
||||||
|
SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const {
|
||||||
|
Result.append(Attachments.begin(), Attachments.end());
|
||||||
|
|
||||||
|
// Sort the resulting array so it is stable.
|
||||||
|
if (Result.size() > 1)
|
||||||
|
array_pod_sort(Result.begin(), Result.end());
|
||||||
|
}
|
||||||
|
|
||||||
void Instruction::setMetadata(StringRef Kind, MDNode *Node) {
|
void Instruction::setMetadata(StringRef Kind, MDNode *Node) {
|
||||||
if (!Node && !hasMetadata())
|
if (!Node && !hasMetadata())
|
||||||
@ -1007,12 +1051,9 @@ void Instruction::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto &Info = InstructionMetadata[this];
|
auto &Info = InstructionMetadata[this];
|
||||||
Info.erase(std::remove_if(
|
Info.remove_if([&KnownSet](const std::pair<unsigned, TrackingMDNodeRef> &I) {
|
||||||
Info.begin(), Info.end(),
|
return !KnownSet.count(I.first);
|
||||||
[&KnownSet](const std::pair<unsigned, TrackingMDNodeRef> &I) {
|
});
|
||||||
return !KnownSet.count(I.first);
|
|
||||||
}),
|
|
||||||
Info.end());
|
|
||||||
|
|
||||||
if (Info.empty()) {
|
if (Info.empty()) {
|
||||||
// Drop our entry at the store.
|
// Drop our entry at the store.
|
||||||
@ -1039,20 +1080,9 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
|
|||||||
auto &Info = getContext().pImpl->InstructionMetadata[this];
|
auto &Info = getContext().pImpl->InstructionMetadata[this];
|
||||||
assert(!Info.empty() == hasMetadataHashEntry() &&
|
assert(!Info.empty() == hasMetadataHashEntry() &&
|
||||||
"HasMetadata bit is wonked");
|
"HasMetadata bit is wonked");
|
||||||
if (Info.empty()) {
|
if (Info.empty())
|
||||||
setHasMetadataHashEntry(true);
|
setHasMetadataHashEntry(true);
|
||||||
} else {
|
Info.set(KindID, *Node);
|
||||||
// Handle replacement of an existing value.
|
|
||||||
for (auto &P : Info)
|
|
||||||
if (P.first == KindID) {
|
|
||||||
P.second.reset(Node);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No replacement, just add it to the list.
|
|
||||||
Info.emplace_back(std::piecewise_construct, std::make_tuple(KindID),
|
|
||||||
std::make_tuple(Node));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1064,22 +1094,14 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
|
|||||||
return; // Nothing to remove!
|
return; // Nothing to remove!
|
||||||
auto &Info = getContext().pImpl->InstructionMetadata[this];
|
auto &Info = getContext().pImpl->InstructionMetadata[this];
|
||||||
|
|
||||||
// Common case is removing the only entry.
|
|
||||||
if (Info.size() == 1 && Info[0].first == KindID) {
|
|
||||||
getContext().pImpl->InstructionMetadata.erase(this);
|
|
||||||
setHasMetadataHashEntry(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle removal of an existing value.
|
// Handle removal of an existing value.
|
||||||
for (unsigned i = 0, e = Info.size(); i != e; ++i)
|
Info.erase(KindID);
|
||||||
if (Info[i].first == KindID) {
|
|
||||||
Info[i] = std::move(Info.back());
|
if (!Info.empty())
|
||||||
Info.pop_back();
|
return;
|
||||||
assert(!Info.empty() && "Removing last entry should be handled above");
|
|
||||||
return;
|
getContext().pImpl->InstructionMetadata.erase(this);
|
||||||
}
|
setHasMetadataHashEntry(false);
|
||||||
// Otherwise, removing an entry that doesn't exist on the instruction.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instruction::setAAMetadata(const AAMDNodes &N) {
|
void Instruction::setAAMetadata(const AAMDNodes &N) {
|
||||||
@ -1093,15 +1115,12 @@ MDNode *Instruction::getMetadataImpl(unsigned KindID) const {
|
|||||||
if (KindID == LLVMContext::MD_dbg)
|
if (KindID == LLVMContext::MD_dbg)
|
||||||
return DbgLoc.getAsMDNode();
|
return DbgLoc.getAsMDNode();
|
||||||
|
|
||||||
if (!hasMetadataHashEntry()) return nullptr;
|
if (!hasMetadataHashEntry())
|
||||||
|
return nullptr;
|
||||||
auto &Info = getContext().pImpl->InstructionMetadata[this];
|
auto &Info = getContext().pImpl->InstructionMetadata[this];
|
||||||
assert(!Info.empty() && "bit out of sync with hash table");
|
assert(!Info.empty() && "bit out of sync with hash table");
|
||||||
|
|
||||||
for (const auto &I : Info)
|
return Info.lookup(KindID);
|
||||||
if (I.first == KindID)
|
|
||||||
return I.second;
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instruction::getAllMetadataImpl(
|
void Instruction::getAllMetadataImpl(
|
||||||
@ -1120,14 +1139,7 @@ void Instruction::getAllMetadataImpl(
|
|||||||
"Shouldn't have called this");
|
"Shouldn't have called this");
|
||||||
const auto &Info = getContext().pImpl->InstructionMetadata.find(this)->second;
|
const auto &Info = getContext().pImpl->InstructionMetadata.find(this)->second;
|
||||||
assert(!Info.empty() && "Shouldn't have called this");
|
assert(!Info.empty() && "Shouldn't have called this");
|
||||||
|
Info.getAll(Result);
|
||||||
Result.reserve(Result.size() + Info.size());
|
|
||||||
for (auto &I : Info)
|
|
||||||
Result.push_back(std::make_pair(I.first, cast<MDNode>(I.second.get())));
|
|
||||||
|
|
||||||
// Sort the resulting array so it is stable.
|
|
||||||
if (Result.size() > 1)
|
|
||||||
array_pod_sort(Result.begin(), Result.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instruction::getAllMetadataOtherThanDebugLocImpl(
|
void Instruction::getAllMetadataOtherThanDebugLocImpl(
|
||||||
@ -1138,13 +1150,7 @@ void Instruction::getAllMetadataOtherThanDebugLocImpl(
|
|||||||
"Shouldn't have called this");
|
"Shouldn't have called this");
|
||||||
const auto &Info = getContext().pImpl->InstructionMetadata.find(this)->second;
|
const auto &Info = getContext().pImpl->InstructionMetadata.find(this)->second;
|
||||||
assert(!Info.empty() && "Shouldn't have called this");
|
assert(!Info.empty() && "Shouldn't have called this");
|
||||||
Result.reserve(Result.size() + Info.size());
|
Info.getAll(Result);
|
||||||
for (auto &I : Info)
|
|
||||||
Result.push_back(std::make_pair(I.first, cast<MDNode>(I.second.get())));
|
|
||||||
|
|
||||||
// Sort the resulting array so it is stable.
|
|
||||||
if (Result.size() > 1)
|
|
||||||
array_pod_sort(Result.begin(), Result.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// clearMetadataHashEntries - Clear all hashtable-based metadata from
|
/// clearMetadataHashEntries - Clear all hashtable-based metadata from
|
||||||
|
Loading…
x
Reference in New Issue
Block a user