summaryrefslogtreecommitdiff
path: root/lib/IR
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-01-12 20:09:34 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-01-12 20:09:34 +0000
commitae9e15f9145ea6da81c297ac01dd42d1330c52ad (patch)
tree90cfdebf35f836ee8745a08649291e6bee7bada0 /lib/IR
parent2d88dc293bd5209ceb4ccb61a41d53a23cc09f20 (diff)
IR: Split GenericMDNode into MDTuple and UniquableMDNode
Split `GenericMDNode` into two classes (with more descriptive names). - `UniquableMDNode` will be a common subclass for `MDNode`s that are sometimes uniqued like constants, and sometimes 'distinct'. This class gets the (short-lived) RAUW support and related API. - `MDTuple` is the basic tuple that has always been returned by `MDNode::get()`. This is as opposed to more specific nodes to be added soon, which have additional fields, custom assembly syntax, and extra semantics. This class gets the hash-related logic, since other sublcasses of `UniquableMDNode` may need to hash based on other fields. To keep this diff from getting too big, I've added casts to `MDTuple` that won't really scale as new subclasses of `UniquableMDNode` are added, but I'll clean those up incrementally. (No functionality change intended.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225682 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r--lib/IR/DIBuilder.cpp5
-rw-r--r--lib/IR/LLVMContextImpl.cpp20
-rw-r--r--lib/IR/LLVMContextImpl.h28
-rw-r--r--lib/IR/Metadata.cpp75
-rw-r--r--lib/IR/MetadataTracking.cpp4
5 files changed, 68 insertions, 64 deletions
diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp
index 6485ca5a003..856bb3c3375 100644
--- a/lib/IR/DIBuilder.cpp
+++ b/lib/IR/DIBuilder.cpp
@@ -55,7 +55,8 @@ DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes)
AllowUnresolvedNodes(AllowUnresolvedNodes) {}
static bool isUnresolved(MDNode *N) {
- return N && (isa<MDNodeFwdDecl>(N) || !cast<GenericMDNode>(N)->isResolved());
+ return N &&
+ (isa<MDNodeFwdDecl>(N) || !cast<UniquableMDNode>(N)->isResolved());
}
void DIBuilder::trackIfUnresolved(MDNode *N) {
@@ -110,7 +111,7 @@ void DIBuilder::finalize() {
// cycles.
for (const auto &N : UnresolvedNodes)
if (N)
- cast<GenericMDNode>(N)->resolveCycles();
+ cast<UniquableMDNode>(N)->resolveCycles();
UnresolvedNodes.clear();
// Can't handle unresolved nodes anymore.
diff --git a/lib/IR/LLVMContextImpl.cpp b/lib/IR/LLVMContextImpl.cpp
index 7c34f0949a4..a9268b46488 100644
--- a/lib/IR/LLVMContextImpl.cpp
+++ b/lib/IR/LLVMContextImpl.cpp
@@ -135,17 +135,17 @@ LLVMContextImpl::~LLVMContextImpl() {
for (auto &Pair : ValuesAsMetadata)
delete Pair.second;
- // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet
- // and the NonUniquedMDNodes sets, so copy the values out first.
- SmallVector<GenericMDNode *, 8> MDNodes;
- MDNodes.reserve(MDNodeSet.size() + NonUniquedMDNodes.size());
- MDNodes.append(MDNodeSet.begin(), MDNodeSet.end());
- MDNodes.append(NonUniquedMDNodes.begin(), NonUniquedMDNodes.end());
- for (GenericMDNode *I : MDNodes)
+ // Destroy MDNodes. ~MDNode can move and remove nodes between the MDTuples
+ // and the DistinctMDNodes sets, so copy the values out first.
+ SmallVector<UniquableMDNode *, 8> Uniquables;
+ Uniquables.reserve(MDTuples.size() + DistinctMDNodes.size());
+ Uniquables.append(MDTuples.begin(), MDTuples.end());
+ Uniquables.append(DistinctMDNodes.begin(), DistinctMDNodes.end());
+ for (UniquableMDNode *I : Uniquables)
I->dropAllReferences();
- for (GenericMDNode *I : MDNodes)
- delete I;
- assert(MDNodeSet.empty() && NonUniquedMDNodes.empty() &&
+ for (UniquableMDNode *I : Uniquables)
+ delete cast<MDTuple>(I);
+ assert(MDTuples.empty() && DistinctMDNodes.empty() &&
"Destroying all MDNodes didn't empty the Context's sets.");
// Destroy MDStrings.
diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h
index a9de5c78822..11b8d38f9af 100644
--- a/lib/IR/LLVMContextImpl.h
+++ b/lib/IR/LLVMContextImpl.h
@@ -166,11 +166,11 @@ struct FunctionTypeKeyInfo {
}
};
-/// \brief DenseMapInfo for GenericMDNode.
+/// \brief DenseMapInfo for MDTuple.
///
/// Note that we don't need the is-function-local bit, since that's implicit in
/// the operands.
-struct GenericMDNodeInfo {
+struct MDTupleInfo {
struct KeyTy {
ArrayRef<Metadata *> RawOps;
ArrayRef<MDOperand> Ops;
@@ -179,10 +179,10 @@ struct GenericMDNodeInfo {
KeyTy(ArrayRef<Metadata *> Ops)
: RawOps(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {}
- KeyTy(GenericMDNode *N)
+ KeyTy(MDTuple *N)
: Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {}
- bool operator==(const GenericMDNode *RHS) const {
+ bool operator==(const MDTuple *RHS) const {
if (RHS == getEmptyKey() || RHS == getTombstoneKey())
return false;
if (Hash != RHS->getHash())
@@ -191,26 +191,26 @@ struct GenericMDNodeInfo {
return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS);
}
template <class T>
- static bool compareOps(ArrayRef<T> Ops, const GenericMDNode *RHS) {
+ static bool compareOps(ArrayRef<T> Ops, const MDTuple *RHS) {
if (Ops.size() != RHS->getNumOperands())
return false;
return std::equal(Ops.begin(), Ops.end(), RHS->op_begin());
}
};
- static inline GenericMDNode *getEmptyKey() {
- return DenseMapInfo<GenericMDNode *>::getEmptyKey();
+ static inline MDTuple *getEmptyKey() {
+ return DenseMapInfo<MDTuple *>::getEmptyKey();
}
- static inline GenericMDNode *getTombstoneKey() {
- return DenseMapInfo<GenericMDNode *>::getTombstoneKey();
+ static inline MDTuple *getTombstoneKey() {
+ return DenseMapInfo<MDTuple *>::getTombstoneKey();
}
static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; }
- static unsigned getHashValue(const GenericMDNode *U) {
+ static unsigned getHashValue(const MDTuple *U) {
return U->getHash();
}
- static bool isEqual(const KeyTy &LHS, const GenericMDNode *RHS) {
+ static bool isEqual(const KeyTy &LHS, const MDTuple *RHS) {
return LHS == RHS;
}
- static bool isEqual(const GenericMDNode *LHS, const GenericMDNode *RHS) {
+ static bool isEqual(const MDTuple *LHS, const MDTuple *RHS) {
return LHS == RHS;
}
};
@@ -245,13 +245,13 @@ public:
DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;
DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;
- DenseSet<GenericMDNode *, GenericMDNodeInfo> MDNodeSet;
+ DenseSet<MDTuple *, MDTupleInfo> MDTuples;
// MDNodes may be uniqued or not uniqued. When they're not uniqued, they
// aren't in the MDNodeSet, but they're still shared between objects, so no
// one object can destroy them. This set allows us to at least destroy them
// on Context destruction.
- SmallPtrSet<GenericMDNode *, 1> NonUniquedMDNodes;
+ SmallPtrSet<UniquableMDNode *, 1> DistinctMDNodes;
DenseMap<Type*, ConstantAggregateZero*> CAZConstants;
diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp
index 859512db001..282ea49aa41 100644
--- a/lib/IR/Metadata.cpp
+++ b/lib/IR/Metadata.cpp
@@ -222,8 +222,8 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) {
if (Owner.is<MetadataAsValue *>())
continue;
- // Resolve GenericMDNodes that point at this.
- auto *OwnerMD = dyn_cast<GenericMDNode>(Owner.get<Metadata *>());
+ // Resolve UniquableMDNodes that point at this.
+ auto *OwnerMD = dyn_cast<UniquableMDNode>(Owner.get<Metadata *>());
if (!OwnerMD)
continue;
if (OwnerMD->isResolved())
@@ -400,7 +400,7 @@ MDNode::MDNode(LLVMContext &Context, unsigned ID, ArrayRef<Metadata *> MDs)
bool MDNode::isResolved() const {
if (isa<MDNodeFwdDecl>(this))
return false;
- return cast<GenericMDNode>(this)->isResolved();
+ return cast<UniquableMDNode>(this)->isResolved();
}
static bool isOperandUnresolved(Metadata *Op) {
@@ -409,9 +409,9 @@ static bool isOperandUnresolved(Metadata *Op) {
return false;
}
-GenericMDNode::GenericMDNode(LLVMContext &C, ArrayRef<Metadata *> Vals,
- bool AllowRAUW)
- : MDNode(C, GenericMDNodeKind, Vals) {
+UniquableMDNode::UniquableMDNode(LLVMContext &C, unsigned ID,
+ ArrayRef<Metadata *> Vals, bool AllowRAUW)
+ : MDNode(C, ID, Vals) {
if (!AllowRAUW)
return;
@@ -427,16 +427,14 @@ GenericMDNode::GenericMDNode(LLVMContext &C, ArrayRef<Metadata *> Vals,
SubclassData32 = NumUnresolved;
}
-GenericMDNode::~GenericMDNode() {
- LLVMContextImpl *pImpl = getContext().pImpl;
+UniquableMDNode::~UniquableMDNode() {
if (isStoredDistinctInContext())
- pImpl->NonUniquedMDNodes.erase(this);
- else
- pImpl->MDNodeSet.erase(this);
+ getContext().pImpl->DistinctMDNodes.erase(this);
+
dropAllReferences();
}
-void GenericMDNode::resolve() {
+void UniquableMDNode::resolve() {
assert(!isResolved() && "Expected this to be unresolved");
// Move the map, so that this immediately looks resolved.
@@ -448,7 +446,7 @@ void GenericMDNode::resolve() {
Uses->resolveAllUses();
}
-void GenericMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) {
+void UniquableMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) {
assert(SubclassData32 != 0 && "Expected unresolved operands");
// Check if an operand was resolved.
@@ -458,13 +456,13 @@ void GenericMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) {
decrementUnresolvedOperandCount();
}
-void GenericMDNode::decrementUnresolvedOperandCount() {
+void UniquableMDNode::decrementUnresolvedOperandCount() {
if (!--SubclassData32)
// Last unresolved operand has just been resolved.
resolve();
}
-void GenericMDNode::resolveCycles() {
+void UniquableMDNode::resolveCycles() {
if (isResolved())
return;
@@ -477,13 +475,18 @@ void GenericMDNode::resolveCycles() {
continue;
assert(!isa<MDNodeFwdDecl>(Op) &&
"Expected all forward declarations to be resolved");
- if (auto *N = dyn_cast<GenericMDNode>(Op))
+ if (auto *N = dyn_cast<UniquableMDNode>(Op))
if (!N->isResolved())
N->resolveCycles();
}
}
-void GenericMDNode::recalculateHash() {
+MDTuple::~MDTuple() {
+ if (!isStoredDistinctInContext())
+ getContext().pImpl->MDTuples.erase(this);
+}
+
+void MDTuple::recalculateHash() {
setHash(hash_combine_range(op_begin(), op_end()));
#ifndef NDEBUG
{
@@ -498,10 +501,10 @@ void GenericMDNode::recalculateHash() {
void MDNode::dropAllReferences() {
for (unsigned I = 0, E = NumOperands; I != E; ++I)
setOperand(I, nullptr);
- if (auto *G = dyn_cast<GenericMDNode>(this))
- if (!G->isResolved()) {
- G->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false);
- G->ReplaceableUses.reset();
+ if (auto *N = dyn_cast<UniquableMDNode>(this))
+ if (!N->isResolved()) {
+ N->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false);
+ N->ReplaceableUses.reset();
}
}
@@ -522,7 +525,7 @@ namespace llvm {
static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }
}
-void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
+void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *New) {
unsigned Op = static_cast<MDOperand *>(Ref) - op_begin();
assert(Op < getNumOperands() && "Expected valid operand");
@@ -534,8 +537,8 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
return;
}
- auto &Store = getContext().pImpl->MDNodeSet;
- Store.erase(this);
+ auto &Store = getContext().pImpl->MDTuples;
+ Store.erase(cast<MDTuple>(this));
Metadata *Old = getOperand(Op);
setOperand(Op, New);
@@ -549,11 +552,11 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
}
// Re-unique the node.
- recalculateHash();
- GenericMDNodeInfo::KeyTy Key(this);
+ cast<MDTuple>(this)->recalculateHash();
+ MDTupleInfo::KeyTy Key(cast<MDTuple>(this));
auto I = Store.find_as(Key);
if (I == Store.end()) {
- Store.insert(this);
+ Store.insert(cast<MDTuple>(this));
if (!isResolved())
resolveAfterOperandChange(Old, New);
@@ -570,7 +573,7 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
for (unsigned O = 0, E = getNumOperands(); O != E; ++O)
setOperand(O, nullptr);
ReplaceableUses->replaceAllUsesWith(*I);
- delete this;
+ delete cast<MDTuple>(this);
return;
}
@@ -580,9 +583,9 @@ void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {
MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Metadata *> MDs,
bool Insert) {
- auto &Store = Context.pImpl->MDNodeSet;
+ auto &Store = Context.pImpl->MDTuples;
- GenericMDNodeInfo::KeyTy Key(MDs);
+ MDTupleInfo::KeyTy Key(MDs);
auto I = Store.find_as(Key);
if (I != Store.end())
return *I;
@@ -590,14 +593,14 @@ MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Metadata *> MDs,
return nullptr;
// Coallocate space for the node and Operands together, then placement new.
- auto *N = new (MDs.size()) GenericMDNode(Context, MDs, /* AllowRAUW */ true);
+ auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ true);
N->setHash(Key.Hash);
Store.insert(N);
return N;
}
MDNode *MDNode::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
- auto *N = new (MDs.size()) GenericMDNode(Context, MDs, /* AllowRAUW */ false);
+ auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ false);
N->storeDistinctInContext();
return N;
}
@@ -616,9 +619,9 @@ void MDNode::deleteTemporary(MDNode *N) {
void MDNode::storeDistinctInContext() {
assert(!IsDistinctInContext && "Expected newly distinct metadata");
IsDistinctInContext = true;
- auto *G = cast<GenericMDNode>(this);
- G->setHash(0);
- getContext().pImpl->NonUniquedMDNodes.insert(G);
+ auto *T = cast<MDTuple>(this);
+ T->setHash(0);
+ getContext().pImpl->DistinctMDNodes.insert(T);
}
void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
@@ -630,7 +633,7 @@ void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
return;
}
- cast<GenericMDNode>(this)->handleChangedOperand(mutable_begin() + I, New);
+ cast<UniquableMDNode>(this)->handleChangedOperand(mutable_begin() + I, New);
}
void MDNode::setOperand(unsigned I, Metadata *New) {
diff --git a/lib/IR/MetadataTracking.cpp b/lib/IR/MetadataTracking.cpp
index 5b4b55586a9..ba97ca033a4 100644
--- a/lib/IR/MetadataTracking.cpp
+++ b/lib/IR/MetadataTracking.cpp
@@ -18,8 +18,8 @@ using namespace llvm;
ReplaceableMetadataImpl *ReplaceableMetadataImpl::get(Metadata &MD) {
if (auto *N = dyn_cast<MDNode>(&MD)) {
- if (auto *G = dyn_cast<GenericMDNode>(N))
- return G->ReplaceableUses.get();
+ if (auto *U = dyn_cast<UniquableMDNode>(N))
+ return U->ReplaceableUses.get();
return cast<MDNodeFwdDecl>(N);
}
return dyn_cast<ValueAsMetadata>(&MD);